Spring-retry 優雅的實現循環重試功能

引言

     在實際的應用場景中,可能經常會遇到,當請求一個接口調一個服務的時候,出現異常或網絡出現故障的情況下就會失敗,而對於那些重要的服務當失敗後,可能我們就會進行重試,多調用幾次,如果還是失敗再另外進行單獨處理。接下來,就是要講解的重點內容,我們可以通過@Retryable註解,優雅的實現循環重試功能。

1:引入依賴

<!-- spring-retry -->
<dependency>
    <groupId>org.springframework.retry</groupId>
     <artifactId>spring-retry</artifactId>
 </dependency>

2:在啓動類上開啓retry重試功能

package com.patent.cloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.retry.annotation.EnableRetry;

@SpringBootApplication
@EnableRetry
public class PatenCloudApplication {

    public static void main(String[] args) {
        SpringApplication.run(PatenCloudApplication.class, args);
    }
}

3:業務處理,在要調用的方法上加上@Retryable註解

   @Autowired
    private VehicleLocationDataService vehicleLocationDataService;

    /**
     * 需要在啓動類中添加@EnableRetry註釋以開啓重試功能,最後在相應的方法上添加@Retryable註解。
     * @Recover註解,重試完成之後執行的回調方法
     * 重試機制,如果調用方法過程中觸發了RuntimeException異常,則20秒後重試一次,最多重試3次,三次重試後會觸發recover方法
     * @param orderNo
     * @param chassisNo
     * @param carStatus
     */
    @GetMapping("/retryMyTest")
    @Retryable(value = RuntimeException.class,maxAttempts = 3, backoff = @Backoff(value = 10000L), recover = "recover", listeners = {"myRetryListener"})
    public void retry(String orderNo, String chassisNo, String carStatus) throws RuntimeException {
        vehicleLocationDataService.retryMyTest(orderNo,chassisNo,carStatus);
    }

4:retryMyTest方法的邏輯處理

package com.patent.cloud.retry;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

@Slf4j
@Service
public class VehicleLocationDataService {

    public  static  Integer retryCount = 1;

    public void retryMyTest(String orderNo, String chassisNo, String carStatus){
        boolean flag = false;
        if("P8012985".equals(chassisNo)){
            flag = true;
        }
        if(retryCount==4){
            retryCount =1;
        }
        if(!flag){
           log.info("有異常哦,我再試多幾次看下還有沒異常, 重試第{}次, {},{},{}",retryCount, orderNo,chassisNo,carStatus);
           retryCount ++;
            throw new RuntimeException("調用失敗!");
        }
    }
}

當程序出現RuntimeException的時候,就好觸發重試

5:recover方法,上邊定義了maxAttempts 爲3,也就是說,重試三次後,如果還失敗了,則調用recover方法,需要在方法上標註@Recover註解

@Recover
public void recover(RuntimeException runtimeException,String orderNo, String chassisNo, String carStatus) {
  log.info("=======觸發重試了recover方法======{}==={}=={}===",orderNo,chassisNo,carStatus);
}

6:監聽,同時還是對重試方法進行了監聽,如我們在方法retry上,加了listeners 監聽

package com.patent.cloud.retry;

import lombok.extern.slf4j.Slf4j;
import org.springframework.retry.RetryCallback;
import org.springframework.retry.RetryContext;
import org.springframework.retry.listener.RetryListenerSupport;
import org.springframework.stereotype.Service;

@Slf4j
@Service
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;
    }

}

7:運行結果

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章