天天看點

spring-retry使用介紹

前言

以往我們在進行網絡請求的時候,需要考慮網絡異常的情況,本文就介紹了利用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哦      

三、總結