zoukankan      html  css  js  c++  java
  • Java一个简单的重试工具包

    在接口调用中由于各种原因,可能会重置失败的任务,使用Guava-Retrying可以方便的实现重试功能。

    首先,需要引用Guava-Retrying的包

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


    代码示例:

    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.util.concurrent.TimeUnit;
    
    import static com.github.rholder.retry.WaitStrategies.incrementingWait;
    
    /**
     * @author wangxuexing
     * @descrption
     * @date
     */
    public class RetryDemo {
        public static void main(String[] args) {
            Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder().
                                        //如果异常会重试
                                        retryIfException().
                                        //如果结果为false会重试
                                        retryIfResult(Predicates.equalTo(false)).
                                        //重调策略
                                        withWaitStrategy(incrementingWait(30, TimeUnit.SECONDS, 30, TimeUnit.SECONDS)).
                                        //尝试次数
                                        withStopStrategy(StopStrategies.stopAfterAttempt(3)).
                                        //注册监听
                                        withRetryListener(new MyRetryListener()).build();
            try {
                retryer.call(new TaskCallable());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    其中TaskCallable是任务的具体实现类,它实现了Callable接口

    import java.util.concurrent.Callable;
    
    /**
     * @author wangxuexing
     * @descrption
     * @date
     */
    public class TaskCallable implements Callable<Boolean> {
    
        public Boolean call() throws Exception {
            return false;
        }
    }
    另外,MyRetryListener监听实现了RetryListener接口,每次重试都会回调注册的监听
    import com.github.rholder.retry.Attempt;
    import com.github.rholder.retry.RetryListener;
    
    /**
     * @author wangxuexing
     * @descrption
     * @date
     */
    public class MyRetryListener implements RetryListener {
        public <V> void onRetry(Attempt<V> attempt) {
            System.out.print("[retry]time=" + attempt.getAttemptNumber());
            // 距离第一次重试的延迟
            System.out.print(",delay=" + attempt.getDelaySinceFirstAttempt());
    
            // 重试结果: 是异常终止, 还是正常返回
            System.out.print(",hasException=" + attempt.hasException());
            System.out.print(",hasResult=" + attempt.hasResult());
    
            // 是什么原因导致异常
            if (attempt.hasException()) {
                System.out.print(",causeBy=" + attempt.getExceptionCause().toString());
            } else {// 正常返回时的结果
                System.out.print(",result=" + attempt.getResult());
            }
            System.out.println();
        }
    }

    执行一下main方法,可以看到执行的结果:

    [retry]time=1,delay=0,hasException=false,hasResult=true,result=false
    [retry]time=2,delay=30000,hasException=false,hasResult=true,result=false
    [retry]time=3,delay=90000,hasException=false,hasResult=true,result=false
    com.github.rholder.retry.RetryException: Retrying failed to complete successfully after 3 attempts.
    	at com.github.rholder.retry.Retryer.call(Retryer.java:174)
    	at test.retryer.RetryDemo.main(RetryDemo.java:32)
    

      

    下面详细分析一下:

    RetryerBuilder是一个factory创建者,可以定制设置重试源且可以支持多个重试源,可以配置重试次数或重试超时时间,以及可以配置等待时间间隔,创建重试者Retryer实例。

    RetryerBuilder的重试源支持Exception异常对象 和自定义断言对象,通过retryIfException 和retryIfResult设置,同时支持多个且能兼容。
    retryIfException,抛出runtime异常、checked异常时都会重试,但是抛出error不会重试。
    retryIfRuntimeException只会在抛runtime异常的时候才重试,checked异常和error都不重试。
    retryIfExceptionOfType允许我们只在发生特定异常的时候才重试,比如NullPointerException和IllegalStateException都属于runtime异常,也包括自定义的error
    retryIfResult可以指定你的Callable方法在返回值的时候进行重试

    StopStrategy:停止重试策略,提供三种:
    StopAfterDelayStrategy 设定一个最长允许的执行时间;比如设定最长执行10s,无论任务执行次数,只要重试的时候超出了最长时间,则任务终止,并返回重试异常RetryException。
    NeverStopStrategy 不停止,用于需要一直轮训知道返回期望结果的情况。

    StopAfterAttemptStrategy 设定最大重试次数,如果超出最大重试次数则停止重试,并返回重试异常。

    WaitStrategy:等待时长策略(控制时间间隔),返回结果为下次执行时长:
    FixedWaitStrategy 固定等待时长策略。
    RandomWaitStrategy 随机等待时长策略(可以提供一个最小和最大时长,等待时长为其区间随机值)。
    IncrementingWaitStrategy 递增等待时长策略(提供一个初始值和步长,等待时间随重试次数增加而增加)。
    ExponentialWaitStrategy 指数等待时长策略。
    FibonacciWaitStrategy Fibonacci 等待时长策略。
    ExceptionWaitStrategy 异常时长等待策略。
    CompositeWaitStrategy 复合时长等待策略。

  • 相关阅读:
    vue table 中 列 加上 下划线和click 方法
    vue 比较好的学习文章
    Hive 以及mysql 中如何做except 数据操作
    oracle 日期维表 原始版本 带注解
    RMI 实现的rpc 远程过程调用 Java
    剑指offer20:定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。
    剑指offer19:按照从外向里以顺时针的顺序依次打印出每一个数字,4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
    模拟通讯录
    剑指offer17:输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
    剑指offer16:输入两个单调递增的链表,合成后的链表满足单调不减规则。
  • 原文地址:https://www.cnblogs.com/barrywxx/p/11784053.html
Copyright © 2011-2022 走看看