Guava Retryer

182 阅读1分钟
  1. 引入Maven依赖

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

重试失败后抛出RetryException异常

@Test
public void retry01() throws InterruptedException {
    Callable<Boolean> callable = new Callable<Boolean>() {
        public Boolean call() throws Exception {
            log.info("execute before");
            Thread.sleep(5000);
            int i = 1 / 0;
            log.info("execute after");
            return null; // do something useful here
        }
    };

    Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
            // 返回false不会重试 Predicates.alwaysFalse()意思是啥
            .retryIfResult(Predicates.or(Predicates.isNull(), Predicates.alwaysFalse()))
            .retryIfExceptionOfType(IOException.class)
            .retryIfRuntimeException()
            .withStopStrategy(StopStrategies.stopAfterAttempt(3))
            //.withWaitStrategy(WaitStrategies.exponentialWait(1000,180, TimeUnit.SECONDS))
            .withWaitStrategy(WaitStrategies.fibonacciWait(1000,180, TimeUnit.SECONDS))
            .withRetryListener(new RetryListener() {
                @Override
                public <V> void onRetry(Attempt<V> attempt) {
                    log.info("[重试次数]{}", attempt.getAttemptNumber());
                    log.info("[重试延迟]{}", attempt.getDelaySinceFirstAttempt());
                    log.info("[重试结果]{}", attempt.hasResult());
                    log.info("[重试异常]{}", attempt.hasException());
                    if(attempt.hasException()){
                        log.error("[重试异常原因]{}", attempt.getExceptionCause().toString());
                    }
                }
            })
            .build();

    Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                Boolean ret = retryer.call(callable);
                log.info("retry result: {}", ret);
            } catch (RetryException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
    });
    thread.start();

    thread.join();
    log.info("main exit");
}

如果抛出的异常,不在重试异常的范围,则不会重试并包装成ExecutionException抛出。

@Test
public void retry02() throws InterruptedException {
    Callable<Boolean> callable = new Callable<Boolean>() {
        public Boolean call() throws Exception {
            log.info("execute before");
            Thread.sleep(5000);
            int i = 1 / 0;
            log.info("execute after");
            return null; // do something useful here
        }
    };

    Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
            .retryIfResult(Predicates.or(Predicates.isNull(), Predicates.alwaysFalse()))
            .retryIfExceptionOfType(IOException.class)
            // 如果抛出的异常,不在重试异常的范围,则不会重试并包装成ExecutionException抛出
            //.retryIfRuntimeException()
            .withStopStrategy(StopStrategies.stopAfterAttempt(3))
            //.withWaitStrategy(WaitStrategies.exponentialWait(1000,180, TimeUnit.SECONDS))
            .withWaitStrategy(WaitStrategies.fibonacciWait(1000,180, TimeUnit.SECONDS))
            .withRetryListener(new RetryListener() {
                @Override
                public <V> void onRetry(Attempt<V> attempt) {
                    log.info("[重试次数]{}", attempt.getAttemptNumber());
                    log.info("[重试延迟]{}", attempt.getDelaySinceFirstAttempt());
                    log.info("[重试结果]{}", attempt.hasResult());
                    log.info("[重试异常]{}", attempt.hasException());
                    if(attempt.hasException()){
                        log.error("[重试异常原因]{}", attempt.getExceptionCause().toString());
                    }
                }
            })
            .build();

    Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                Boolean ret = retryer.call(callable);
                log.info("retry result: {}", ret);
            } catch (RetryException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
    });
    thread.start();

    thread.join();
    log.info("main exit");
}