前言
以往我們在進行網絡請求的時候,需要考慮網絡異常的情況,本文就介紹了利用spring-retry架構進行網絡異常重試的基礎内容。
提示:以下是本篇文章正文内容,下面案例可供參考
一、spring-retry是什麼?
是spring提供的一個重試架構,原本自己實作的重試機制,現在spring幫封裝好提供更加好的編碼體驗。
二、使用步驟
1.引入maven庫
代碼如下(示例):
<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>
2. 在spring啟動類上開啟重試功能
提示:添加@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();
}
}
3.公共業務代碼
@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);
}
}
4. 以往的重試做法
@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();
}
}
}
}
}
5. 使用spring-retry的指令式編碼
5.1 定義重試監聽器
@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;
}
}
5.2 定義重試配置
@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;
}
}
5.3 指令式編碼
@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;
}
);
}
}
6 使用spring-retry的注解式編碼
@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("注解式");
}
}
7 啟動列印效果
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哦