以往我们在进行网络请求的时候,需要考虑网络异常的情况,本文就介绍了利用spring-retry框架进行网络异常重试的基础内容。
提示:以下是本篇文章正文内容,下面案例可供参考
是spring提供的一个重试框架,原本自己实现的重试机制,现在spring帮封装好提供更加好的编码体验。
代码如下(示例):
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.3.9.RELEASE</version>
</dependency>
提示:添加@EnableRetry注解开启
@SpringBootApplication
@EnableRetry
public class SpringRetryDemoApplication {
public static SpringRetryAnnotationService springRetryAnnotationService;
public static SpringRetryImperativeService springRetryImperativeService;
public static TranditionalRetryService tranditionalRetryService;
@Autowired
public void setSpringRetryAnnotationService(SpringRetryAnnotationService springRetryAnnotationService) {
SpringRetryDemoApplication.springRetryAnnotationService = springRetryAnnotationService;
}
@Autowired
public void setSpringRetryImperativeService(SpringRetryImperativeService springRetryImperativeService) {
SpringRetryDemoApplication.springRetryImperativeService = springRetryImperativeService;
}
@Autowired
public void setTranditionalRetryService(TranditionalRetryService tranditionalRetryService) {
SpringRetryDemoApplication.tranditionalRetryService = tranditionalRetryService;
}
public static void main(String[] args) {
SpringApplication.run(SpringRetryDemoApplication.class, args);
springRetryAnnotationService.test();
springRetryImperativeService.test();
tranditionalRetryService.test();
}
}
@Service
@Slf4j
public class CommonService {
public void test(String before) {
for (int i = 0; i < 10; i++) {
if (i == 2) {
log.error("{}:有异常哦,我再试多几次看下还有没异常", before);
throw new RuntimeException();
}
log.info("{}:打印次数: {}", before, i + 1);
}
}
public void recover(String before) {
log.error("{}:还是有异常,程序有bug哦", before);
}
}
@Service
@Slf4j
public class TranditionalRetryService {
@Autowired
CommonService commonService;
public void test() {
// 定义重试次数以及重试时间间隔
int retryCount = 3;
int retryTimeInterval = 3;
for (int r = 0; r < retryCount; r++) {
try {
commonService.test("以前的做法");
} catch (RuntimeException e) {
if (r == retryCount - 1) {
commonService.recover("以前的做法");
return;
}
try {
Thread.sleep(retryTimeInterval * 1000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
}
}
提示:监听重试过程的生命周期
@Slf4j
public class MyRetryListener extends RetryListenerSupport {
@Override
public <T, E extends Throwable> void close(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
log.info("监听到重试过程关闭了");
log.info("=======================================================================");
}
@Override
public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
log.info("监听到重试过程错误了");
}
@Override
public <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback) {
log.info("=======================================================================");
log.info("监听到重试过程开启了");
return true;
}
}
提示:配置RetryTemplate重试模板类
@Configuration
public class RetryConfig {
@Bean
public RetryTemplate retryTemplate() {
// 定义简易重试策略,最大重试次数为3次,重试间隔为3s
RetryTemplate retryTemplate = RetryTemplate.builder()
.maxAttempts(3)
.fixedBackoff(3000)
.retryOn(RuntimeException.class)
.build();
retryTemplate.registerListener(new MyRetryListener());
return retryTemplate;
}
}
@Service
@Slf4j
public class SpringRetryImperativeService {
@Autowired
RetryTemplate retryTemplate;
@Autowired
CommonService commonService;
public void test() {
retryTemplate.execute(
retry -> {
commonService.test("命令式");
return null;
},
recovery -> {
commonService.recover("命令式");
return null;
}
);
}
}
@Service
@Slf4j
public class SpringRetryAnnotationService {
@Autowired
CommonService commonService;
/**
* 如果失败,定义重试3次,重试间隔为3s,指定恢复名称,指定监听器
*/
@Retryable(value = RuntimeException.class, maxAttempts = 3, backoff = @Backoff(value = 3000L), recover = "testRecover", listeners = {"myRetryListener"})
public void test() {
commonService.test("注解式");
}
@Recover
public void testRecover(RuntimeException runtimeException) {
commonService.recover("注解式");
}
}
2022-05-06 11:53:12.044 INFO 21812 --- [ main] c.e.s.listener.MyRetryListener : =======================================================================
2022-05-06 11:53:12.044 INFO 21812 --- [ main] c.e.s.listener.MyRetryListener : 监听到重试过程开启了
2022-05-06 11:53:12.048 INFO 21812 --- [ main] c.e.s.service.CommonService : 注解式:打印次数: 1
2022-05-06 11:53:12.048 INFO 21812 --- [ main] c.e.s.service.CommonService : 注解式:打印次数: 2
2022-05-06 11:53:12.049 ERROR 21812 --- [ main] c.e.s.service.CommonService : 注解式:有异常哦,我再试多几次看下还有没异常
2022-05-06 11:53:12.049 INFO 21812 --- [ main] c.e.s.listener.MyRetryListener : 监听到重试过程错误了
2022-05-06 11:53:15.062 INFO 21812 --- [ main] c.e.s.service.CommonService : 注解式:打印次数: 1
2022-05-06 11:53:15.062 INFO 21812 --- [ main] c.e.s.service.CommonService : 注解式:打印次数: 2
2022-05-06 11:53:15.062 ERROR 21812 --- [ main] c.e.s.service.CommonService : 注解式:有异常哦,我再试多几次看下还有没异常
2022-05-06 11:53:15.062 INFO 21812 --- [ main] c.e.s.listener.MyRetryListener : 监听到重试过程错误了
2022-05-06 11:53:18.065 INFO 21812 --- [ main] c.e.s.service.CommonService : 注解式:打印次数: 1
2022-05-06 11:53:18.065 INFO 21812 --- [ main] c.e.s.service.CommonService : 注解式:打印次数: 2
2022-05-06 11:53:18.065 ERROR 21812 --- [ main] c.e.s.service.CommonService : 注解式:有异常哦,我再试多几次看下还有没异常
2022-05-06 11:53:18.065 INFO 21812 --- [ main] c.e.s.listener.MyRetryListener : 监听到重试过程错误了
2022-05-06 11:53:18.066 ERROR 21812 --- [ main] c.e.s.service.CommonService : 注解式:还是有异常,程序有bug哦
2022-05-06 11:53:18.066 INFO 21812 --- [ main] c.e.s.listener.MyRetryListener : 监听到重试过程关闭了
2022-05-06 11:53:18.066 INFO 21812 --- [ main] c.e.s.listener.MyRetryListener : =======================================================================
2022-05-06 11:53:18.067 INFO 21812 --- [ main] c.e.s.listener.MyRetryListener : =======================================================================
2022-05-06 11:53:18.067 INFO 21812 --- [ main] c.e.s.listener.MyRetryListener : 监听到重试过程开启了
2022-05-06 11:53:18.067 INFO 21812 --- [ main] c.e.s.service.CommonService : 命令式:打印次数: 1
2022-05-06 11:53:18.067 INFO 21812 --- [ main] c.e.s.service.CommonService : 命令式:打印次数: 2
2022-05-06 11:53:18.067 ERROR 21812 --- [ main] c.e.s.service.CommonService : 命令式:有异常哦,我再试多几次看下还有没异常
2022-05-06 11:53:18.067 INFO 21812 --- [ main] c.e.s.listener.MyRetryListener : 监听到重试过程错误了
2022-05-06 11:53:21.079 INFO 21812 --- [ main] c.e.s.service.CommonService : 命令式:打印次数: 1
2022-05-06 11:53:21.079 INFO 21812 --- [ main] c.e.s.service.CommonService : 命令式:打印次数: 2
2022-05-06 11:53:21.079 ERROR 21812 --- [ main] c.e.s.service.CommonService : 命令式:有异常哦,我再试多几次看下还有没异常
2022-05-06 11:53:21.079 INFO 21812 --- [ main] c.e.s.listener.MyRetryListener : 监听到重试过程错误了
2022-05-06 11:53:24.082 INFO 21812 --- [ main] c.e.s.service.CommonService : 命令式:打印次数: 1
2022-05-06 11:53:24.082 INFO 21812 --- [ main] c.e.s.service.CommonService : 命令式:打印次数: 2
2022-05-06 11:53:24.082 ERROR 21812 --- [ main] c.e.s.service.CommonService : 命令式:有异常哦,我再试多几次看下还有没异常
2022-05-06 11:53:24.082 INFO 21812 --- [ main] c.e.s.listener.MyRetryListener : 监听到重试过程错误了
2022-05-06 11:53:24.082 ERROR 21812 --- [ main] c.e.s.service.CommonService : 命令式:还是有异常,程序有bug哦
2022-05-06 11:53:24.082 INFO 21812 --- [ main] c.e.s.listener.MyRetryListener : 监听到重试过程关闭了
2022-05-06 11:53:24.082 INFO 21812 --- [ main] c.e.s.listener.MyRetryListener : =======================================================================
2022-05-06 11:53:24.082 INFO 21812 --- [ main] c.e.s.service.CommonService : 以前的做法:打印次数: 1
2022-05-06 11:53:24.083 INFO 21812 --- [ main] c.e.s.service.CommonService : 以前的做法:打印次数: 2
2022-05-06 11:53:24.083 ERROR 21812 --- [ main] c.e.s.service.CommonService : 以前的做法:有异常哦,我再试多几次看下还有没异常
2022-05-06 11:53:27.084 INFO 21812 --- [ main] c.e.s.service.CommonService : 以前的做法:打印次数: 1
2022-05-06 11:53:27.084 INFO 21812 --- [ main] c.e.s.service.CommonService : 以前的做法:打印次数: 2
2022-05-06 11:53:27.084 ERROR 21812 --- [ main] c.e.s.service.CommonService : 以前的做法:有异常哦,我再试多几次看下还有没异常
2022-05-06 11:53:30.090 INFO 21812 --- [ main] c.e.s.service.CommonService : 以前的做法:打印次数: 1
2022-05-06 11:53:30.090 INFO 21812 --- [ main] c.e.s.service.CommonService : 以前的做法:打印次数: 2
2022-05-06 11:53:30.090 ERROR 21812 --- [ main] c.e.s.service.CommonService : 以前的做法:有异常哦,我再试多几次看下还有没异常
2022-05-06 11:53:30.090 ERROR 21812 --- [ main] c.e.s.service.CommonService : 以前的做法:还是有异常,程序有bug哦
本文仅仅简单介绍了spring-retry的基本使用,相较于以往的做法,个人认为注解式更为简便,命令式看个人喜好,更多使用方法参照github主页
https://github.com/spring-projects/spring-retry
https://gitee.com/teajoy/springboot-modules/tree/master/springboot-retry
先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦