guava-retrying重试工具库
github地址:https://github.com/rholder/guava-retrying
重试触发时机:
-
.方法抛出异常的时候重试
- runtime异常、checked异常和error - retryIfRuntimeException() - retryIfException() - - 自定义异常 - retryIfExceptionOfType()
Retryer<Void> retryer = RetryerBuilder.<Void>newBuilder() .retryIfExceptionOfType(IllegalStateException.class)// 只在抛出IllegalStateException重试 .withStopStrategy(StopStrategies.stopAfterAttempt(3)) // 重试3次后停止 .build();
-
断言
- retryIfResult -
Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder() .retryIfResult(Predicates.equalTo(false)) // 返回false时重试 .retryIfExceptionOfType(IOException.class) // 抛出IOException时重试 .withWaitStrategy(WaitStrategies.fixedWait(200, TimeUnit.MILLISECONDS)) // 200ms后重试 .withStopStrategy(StopStrategies.stopAfterAttempt(3)) // 重试3次后停止 .build();
终止策略StopStrategy
- 重试n次后终止
- StopStrategies.stopAfterAttempt(n)
- 从不终止,一直重试
- StopStrategies.neverStop()
- 一直重试,指定时间过后终止
- StopStrategies.stopAfterDelay(10, TimeUnit.SECONDS)
- 自定义策略
- 实现StopStrategy接口
等待策略WaitStrategy
- 失败后立刻重试,没有等待时间
- WaitStrategies.noWait()
- 间隔固定时间之后重试
- WaitStrategies.fixedWait(1, TimeUnit.SECONDS)
- 间隔随机时间后重试,比如间隔0~3中随机时间后重试
- WaitStrategies.randomWait(3, TimeUnit.SECONDS)
- 最小值,最大值之间的随机时间
- WaitStrategies.randomWait(2, TimeUnit.SECONDS, 5, TimeUnit.SECONDS)
- 增量重试,重试的次数越多,等待时间间隔越长
- WaitStrategies.incrementingWait
- incrementingWait需要传递2个参数,一个是initialSleepTime(第一次到第二次尝试的间隔),一个是increment(每增加一次尝试,需要增加的时间间隔)
- 按照斐波那契数列等待
- WaitStrategies.fibonacciWait()
- 按照指数递增(2的n次方)来等待
- WaitStrategies.exponentialWait
- 根据抛出的异常来决定等待的时间长短,没有什么实际用处
- WaitStrategies.exceptionWait
阻塞策略BlockStrategy
- 阻塞策略用以重试等待
- guava-retrying默认是使用睡眠方式来实现阻塞的,可以响应外部中断请求
AttemptTimeLimiter
- 为了限制任务的执行时间
Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
.retryIfException()
.retryIfResult(Predicates.equalTo(false))
.withAttemptTimeLimiter(AttemptTimeLimiters.fixedTimeLimit(1, TimeUnit.SECONDS))
.withStopStrategy(StopStrategies.stopAfterAttempt(5))
.build();
RetryListener
- 重试之后,做一些额外的处理动作,比如发个告警邮件啥的
- 可以注册多个RetryListener,会按照注册顺序依次调用
注意事项
- 入参:一个实现了业务逻辑的Callable对象;
- 返回值:某次尝试成功后,Callable的返回值
- ExecutionException
- 传入的Callable执行过程中产生了异常,但是我们在构建Retryer对象的时候并没有考虑这种情况,就会抛出这个异常。抛出这异常,也就意味着重试终止
- RetryException
- 当所有重试介绍后,依然不能成功,那么就会抛这异常
Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
.retryIfResult(Predicates.equalTo(false)) // 返回false时重试
// .retryIfExceptionOfType(IOException.class) // 抛出IOException时重试
.withWaitStrategy(WaitStrategies.fixedWait(2000, TimeUnit.MILLISECONDS)) // 200ms后重试
.withStopStrategy(StopStrategies.stopAfterAttempt(3)) // 重试3次后停止
.build();
retryer.call(() -> {
System.out.println("-----");
double random = Math.random();
System.out.println(random);
return random > 5;
});
引用文章地址:https://blog.csdn.net/aitangyong/article/details/53840719?spm=1001.2014.3001.5502.