zoukankan      html  css  js  c++  java
  • 异步回调实现- Guava Retryer

    为什么要使用重试利器Retryer

    在实际开发中我们经常会遇到需要轮询查询一个接果,实现轮询的方式有很多种,我们经常要写许多代码,有时还会怕写出的代码有bug,如果已经有轮子了,我们就没必要重复造轮子了,毕竟时间有限,我们要挣钱。

    github上开源的重试利器: https://github.com/rholder/guava-retrying

    此retry是结合了Callable接口来实现,重试功能的,话不多说,直接上码。

    重试利器maven配置

    <dependency>
          <groupId>com.github.rholder</groupId>
          <artifactId>guava-retrying</artifactId>
          <version>2.0.0</version>
    </dependency>

    重试利器示例

    1.如果想重试几次就结束轮询的话,可参考如下代码

    package com.example.guava;
    
    import com.github.rholder.retry.RetryException;
    import com.github.rholder.retry.Retryer;
    import com.github.rholder.retry.RetryerBuilder;
    import com.github.rholder.retry.StopStrategies;
    import com.google.common.base.Predicates;
    
    import java.io.IOException;
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    
    /**
     * @author: GuanBin
     * @date: Created in 下午4:30 2019/11/3
     */
    public class RetryTest {
    
        public static void main(String[] args) {
            //callable是定义具体的业务操作,并返回该操作结果的返回值
            Callable<Boolean> callable = new Callable<Boolean>() {
                public Boolean call() throws Exception {
                    return true; // do something useful here
                }
            };
    
            //定义retryer,指定轮询条件,及结束条件
            Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
                    .retryIfResult(Predicates.<Boolean>isNull())
                    .retryIfExceptionOfType(IOException.class)
                    .retryIfRuntimeException()
                    .withStopStrategy(StopStrategies.stopAfterAttempt(3))
                    .build();
            try {
                retryer.call(callable);
            } catch (RetryException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
    
    }

    retryer的条件是,callable的返回值是null或者有io异常或者运行时异常,则进行重试,重试次数为3次;

    2.如果想以每隔一段时间的频率重试可参考如下代码

      Retryer<TaskResult> getExecutionStatusRetryer = RetryerBuilder.<TaskResult>newBuilder()
                        .withWaitStrategy(WaitStrategies.fixedWait(5, TimeUnit.SECONDS))
                        .retryIfResult(r -> !Constants.completeStatus.contains(r.getStatus()))
                        .withStopStrategy(StopStrategies.neverStop())
                        .build();
    WaitStrategies定义等待策略:示例是5秒一次就会轮询一次call的实现()
    StopStrategies是定义停止轮询策略的,StopStrategies.neverStop() 若满足轮询条件的话,会一直进行重试下去

    3.创建一个永久重试的重试器,在每次重试失败后以递增的指数退避间隔等待,直到最多5分钟。 5分钟后,每隔5分钟重试一次。

     Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
                    .retryIfExceptionOfType(IOException.class)
                    .retryIfRuntimeException()
                    .withWaitStrategy(WaitStrategies.exponentialWait(100, 5, TimeUnit.MINUTES))
                    .withStopStrategy(StopStrategies.neverStop())
                    .build();

    若第一次重试是100毫秒后重试,若进行第二次则是增加到200毫秒进行重试,依次类推,知道达到5分钟的上限,之后按照5分钟一次的频率进行重试

    有兴趣的可参考 指数回退:https://en.wikipedia.org/wiki/Exponential_backoff

    4.创建一个永久重试的重试器,在每次重试失败后以递增的退避间隔等待,直到最多2分钟。 2分钟后,每隔2分钟重试一次

    Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
            .retryIfExceptionOfType(IOException.class)
            .retryIfRuntimeException()
            .withWaitStrategy(WaitStrategies.fibonacciWait(100, 2, TimeUnit.MINUTES))
            .withStopStrategy(StopStrategies.neverStop())
            .build();

    与指数等待策略类似,FibonacciWaitStrategy遵循的模式是每次尝试失败后等待时间增加。

    FibonacciWaitStrategy是用斐波那契数列来计算等待时间,而不是指数函数。根据目前实践中发现,fibonacciwaitstrategy可能比指数waitstrategy有更好的性能和更好的吞吐量-至少根据不同回退算法在不同重播概率下的性能比较。

     

  • 相关阅读:
    大小端模式
    深入理解c/c++ 内存对齐
    示波器使用
    C结构体
    51单片机内存问题
    S5PV210启动过程详解1
    程序中内存从哪里来
    再论typedef
    ARM体系结构总结
    MMU实验实验
  • 原文地址:https://www.cnblogs.com/guanbin-529/p/11788268.html
Copyright © 2011-2022 走看看