java优雅的重试
java优雅的重试文章目录java优雅的重试一、概述二、java重试框架之guava-retrying1、jar包maven引用2、构建一个重试器,对重试条件,等待策略,停止策略等进行设置3、定义重试的业务4、执行重试5、在spring中优雅的定义全局Retryer一、概述在项目开发中,我们经常会遇到多服务直接互相调用之类的场景,而由于网络的不稳定性,请求可能偶尔失败,如何优雅的进行失败重试...
·
java优雅的重试
文章目录
一、概述
在项目开发中,我们经常会遇到多服务直接互相调用之类的场景,而由于网络的不稳定性,请求可能偶尔失败,如何优雅的进行失败重试,也是我们开发中不得不去考虑的一个问题。
一个基本的重试流程,需要我们去解决最基础的重试要求:
1、在什么条件下进行重试
2、在什么条件下停止重试
然而对于一个设计优良的重试程序,更要去我们去进一步完善实现
1、重试次数设置
2、重试时间间隔
3、重试超时时间
二、java重试框架之guava-retrying
guava-retrying是基于谷歌的核心类库guava的重试实现机制,可以方便快速的解决我们开发场景中常见的重试问题。
1、jar包maven引用
<dependency>
<groupId>com.github.rholder</groupId>
<artifactId>guava-retrying</artifactId>
<version>2.0.0</version>
</dependency>
2、构建一个重试器,对重试条件,等待策略,停止策略等进行设置
Retryer myRetryer = RetryerBuilder.<Boolean>newBuilder()
//retryIf 重试条件
.retryIfException()
.retryIfRuntimeException()
.retryIfExceptionOfType(Exception.class)
.retryIfException(Predicates.equalTo(new Exception()))
.retryIfResult(Predicates.equalTo(false))
//等待策略:每次请求间隔1s
.withWaitStrategy(WaitStrategies.fixedWait(1, TimeUnit.SECONDS))
//停止策略 : 尝试请求6次
.withStopStrategy(StopStrategies.stopAfterAttempt(6))
//时间限制 : 某次请求不得超过2s , 类似: TimeLimiter timeLimiter = new SimpleTimeLimiter();
.withAttemptTimeLimiter(AttemptTimeLimiters.fixedTimeLimit(3, TimeUnit.SECONDS))
.build();
3、定义重试的业务
Callable<Boolean> myServiceCallable = new Callable<Boolean>() {
int times = 1;
@Override
public Boolean call() {
log.info("myService重试第{}次", times);
try {
// 处理业务
handleService();
return true;
} catch (Exception e) {
times++;
return false;
}
}
};
4、执行重试
myRetryer.call(myServiceCallable);
在java8中也可以使用函数式编程,直接调用call方法,更加简明直接
mailRetryer.call(() -> {
try {
// 处理业务
handleService();
return true;
} catch (Exception e) {
return false;
}
});
5、在spring中优雅的定义全局Retryer
在一个大型的项目中,我们不可能去对每一处的业务处理都实现一个重试器,这对资源和内存也是一种浪费,这时候就需要我们对某一组重试机制相同的业务,只创建一各重试器就可以。
在spring中,我们可以利用bean的单例性质,来创建一组全局的重试器。根据业务需要,选择使用不同类型的重试器
@Slf4j
@Component
public class CustomizeRetryer {
//定义发送邮件的重试器
private Retryer<Boolean> mailRetryer;
//定义发送短信的重试器
private Retryer<Boolean> msgRetryer;
@Bean(value = "mailRetryer")
public Retryer mailRetryer(){
log.info("===========init mailRetryer==========");
mailRetryer = RetryerBuilder.<Boolean>newBuilder()
//retryIf 重试条件
.retryIfException()
.retryIfRuntimeException()
.retryIfExceptionOfType(Exception.class)
.retryIfException(Predicates.equalTo(new Exception()))
.retryIfResult(Predicates.equalTo(false))
//等待策略:每次请求间隔1s
.withWaitStrategy(WaitStrategies.fixedWait(1, TimeUnit.SECONDS))
//停止策略 : 尝试请求6次
.withStopStrategy(StopStrategies.stopAfterAttempt(6))
.build();
return mailRetryer;
}
@Bean(value = "msgRetryer")
public Retryer msgRetryer(){
log.info("=========init msgRetryer===========");
msgRetryer = RetryerBuilder.<Boolean>newBuilder()
//retryIf 重试条件
.retryIfException()
.retryIfRuntimeException()
.retryIfExceptionOfType(Exception.class)
.retryIfException(Predicates.equalTo(new Exception()))
.retryIfResult(Predicates.equalTo(false))
//等待策略:每次请求间隔0.2秒
.withWaitStrategy(WaitStrategies.fixedWait(200, TimeUnit.MILLISECONDS))
//停止策略 : 尝试请求9次
.withStopStrategy(StopStrategies.stopAfterAttempt(9))
.build();
return msgRetryer;
}
}
在其他类中引用重试器时可直接通过spring注解的方式来引用
@Autowired
private Retryer mailRetryer;
@Autowired
private Retryer msgRetryer;
更多推荐
已为社区贡献1条内容
所有评论(0)