Spring-retry實現重試
在專案中,呼叫第三方介面響應比較慢,或者由於網路抖動等原因,導致無響應或響應超時的情況,就要用到重試機制。比較簡單成熟的方案就是使用spring-retry
功能,spring-retry
需要使用aop的特性,所以需要引入aspectj
1. 新增依賴
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
2. 核心註解有3個: @EnableRetry
,@Retryable
和 @Recover
@EnableRetry:此註解用於開啟重試框架,可以修飾在SpringBoot啟動類上面,也可以修飾在需要重試的類上
proxyTargetClass:Boolean型別,用於指明代理方式【true:cglib代理,false:jdk動態代理】預設使用jdk動態代理
@Retryable
value:Class[]型別,用於指定需要重試的異常型別,
include:Class[]型別,作用於value類似,區別尚未分析
exclude:Class[]型別,指定不需要重試的異常型別
maxAttemps:int型別,指定最多重試次數,預設3
backoff:Backoff型別,指明補償機制
@BackOff
delay:指定延遲後重試,預設為1000L,即1s後開始重試 ;
multiplier:指定延遲的倍數
@Recover
當重試次數耗盡依然出現異常時,執行此異常對應的@Recover方法。
異常型別需要與Recover方法引數型別保持一致,
recover方法返回值需要與重試方法返回值保證一致
3. 使用步驟
① SpringBoot啟動類上增加@EnableRetry註解
@SpringBootApplication
@EnableRetry
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication .class, args);
}
}
② 介面
@RestController
public class RetryController {
@Autowired
RetryService retryService;
@GetMapping("/retry")
public String retry (@RequestParam("num") final int num) throws Exception {
return retryService.doRetry(num);
}
}
③ 在需要重試的介面上新增@Retryable註解
新增重試註解,當有異常時觸發重試機制,設定重試4次,預設是3.延時2000ms再次執行,每次延時是上次延時的1.5倍.當返回結果不符合要求時,主動報錯觸發重試.
@Retryable(value = Exception.class, maxAttempts = 4, backoff = @Backoff(delay = 2000, multiplier = 1.5))
public String doRetry (int num) throws Exception {
System.err.println("doRetry開始執行" + LocalDateTime.now());
if (num <= 0) {
throw new Exception("異常了");
}
return "輸入的數值是:" + num;
}
④ 增加重試依然失敗後回撥的方法上加@Recover註解,如果不寫,將正常的丟擲異常
@Recover
public String recover (Exception e) {
return "num必須大於0";
}
採坑記錄:
1. retry重試機制無效
由於retry用到了aspect增強,所有會有aspect的坑,就是在同一類中方法內部呼叫,會使aspect增強失效,那麼retry當然也會失效。
public class demo {
public void A() {
B();
}
@Retryable(Exception.class)
public void B() {
throw new RuntimeException("retry...");
}
}
這種情況,方法B是不會重試執行的
2. recover回撥報錯
org.springframework.retry.ExhaustedRetryException: Cannot locate recovery method
報錯顯示找不到recovery方法
解決方案就這這兩句話:
-
異常型別需要與Recover方法引數型別保持一致
-
recover方法返回值需要與重試方法返回值保證一致
異常型別和返回值要一致!
「其他文章」
- postgresql資料庫 timescaledb 時序庫 把大資料量表轉換為超表
- [Python影象處理] 三十六.OpenCV影象幾何變換萬字詳解(平移縮放旋轉、映象仿射透視)
- Debian 10 Buster release party 重慶站
- 乾貨 | 基於 Python 的信用評分模型實戰!
- 不用再等後端的介面啦!這個開源專案花 2 分鐘就能模擬出後端介面
- 圖解ElasticSearch 搜尋原理
- 智算中心作業系統 | 數智化升級的新定海神針
- 6年開源經驗總結出的bug修復技巧,好用!
- Invalid bound statement (not found): com.taotao.mapper.TbItemMapper.selectByExample問題解決
- Spring-retry實現重試
- 初識 D3.js :打造專屬視覺化
- 1-100的和
- CDA LEVEL I 資料分析認證考試模擬題庫(十七) - 知乎
- 作業系統 - Linux
- Unity 3D導航系統(Navigation)
- LinuxMint19 安裝向日葵圖形介面版sunloginclient
- Zabbix_agentd在Win/Linux中的安裝文件
- 執行 ping 命令執行結果的卻是 rm -rf,我太難了……
- 使用Docker部署SpringBoot Vue部落格系統
- Golang雲盤專案:檔案Hash以及秒傳優化