这里使用Google的一个开源包,guava包进行实现,这个包里包含了很多好用的工具类,包括但不限于本地缓存,集合工具包等,我们今天从重试的角度来,使用guava包进行快速的方法重试构建;
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>28.0-jre</version>
</dependency>
<!-- 具体的版本可以通过Maven Repository获取最新的GA版本,我使用的是28.0-->
把方法大致分为无返回值,返回任务执行结果类型,以及有返回值类型三种,大致的代码示意如下,满足日常中的基本需求;
private static final Retryer<Void> EXCEPTION_RETRYER = RetryerBuilder.<Void>newBuilder()
.retryIfException()
.withStopStrategy(StopStrategies.stopAfterAttempt(12))
.withWaitStrategy(WaitStrategies.randomWait(2, TimeUnit.SECONDS, 5, TimeUnit.SECONDS))
.build();
//支持重试策略,当异常的时候进行重试,WaitStrategies指定重试等待策略,支持随机等待时间,withStopStrategy,定义重试的终止次数,再最终重试失败时,会返回一个exception
private static final Retryer<Boolean> RETRYER_TEN_TIMES = RetryerBuilder.<Boolean>newBuilder()
.retryIfResult(result -> !result)
.retryIfException()
.withWaitStrategy(WaitStrategies.randomWait(2, TimeUnit.SECONDS, 5, TimeUnit.SECONDS))
.withStopStrategy(StopStrategies.stopAfterAttempt(10))
.build();
//同时也可以根据返回结果进行重试,retryIfResult会使用Supplier方法的返回值,作为判断的一句,如果执行方法为有返回成功结果的可以考虑这种
private static final Retryer<Object> SUPPLY_RETRYER = RetryerBuilder.<Object>newBuilder()
.retryIfException()
.withStopStrategy(StopStrategies.stopAfterAttempt(12))
.withWaitStrategy(WaitStrategies.randomWait(2, TimeUnit.SECONDS, 5, TimeUnit.SECONDS))
.build();
@SuppressWarnings("unchecked")
public static <T> Retryer<T> createRetryer() {
return (Retryer<T>) SUPPLY_RETRYER;
}
/**
* 使用 Void 类型重试器,执行无返回值的任务
*
* @param runnable 执行逻辑
*/
public <T> T supplyWhenException(Callable<T> runnable) {
try {
Retryer<T> retryer = createRetryer();
return retryer.call(runnable);
} catch (Exception e) {
log.error("最终重试失败,执行逻辑异常:", e);
throw new RuntimeException("任务执行失败", e);
}
}
//当然,如果方法本身有返回值,又想使用到返回的返回结果,用一公共的重试策略+强转的方式,支持Supplier方法返回的泛型值