Spring @Retryable實現接口自動重試

背景: 在實際項目中,咱們在與其餘第三方業務接口進行交互時,可能會由於一些網絡波動致使超時失敗,可是並不能只一次失敗就斷定接口請求失敗,應該考慮重試屢次後若是仍然失敗,才返回請求失敗。spring

解決方案:markdown

解決方案一:try-catch 簡單重試網絡

經過判斷返回結果或監聽異常斷定是否重試,同時爲了解決當即重試的無效執行(假設異常是有外部執行不穩定致使的),休眠必定延遲時間從新執行功能邏輯。測試

image.png

可是這樣會存在一個問題,那就是若是是請求參數不正常,那麼就會一直重試下去,變成了死循環。spa

image.png

這樣確定不是咱們想要的解決方案,因此咱們須要添加限制,判斷重試多少次之後仍然失敗,就返回失敗結果。3d

image.png

而後此次再看執行結果,此次就按照咱們設置的次數進行重試了,已經達到了業務需求code

image.png

結論:try-catch再加上提早設定重試次數,這樣已能夠知足咱們重試機制了,可是有沒有更簡單的方法呢?答案是確定的。orm

解決方案二:Spring @Retryable 註解實現接口

@Retryable是Spring提供的可重試註解,爲了使用spring提供的重試機制ip

在pom文件中添加相應的依賴

<!-- spring retry 自動重試機制-->
<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
    <version>1.2.4.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.4</version>
</dependency>
<!-- spring retry 自動重試機制-->
複製代碼

啓動類添加註解

@EnableRetry
複製代碼

在須要重試的方法上添加註解@Retryable

@Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 2000L, multiplier = 1.5))
複製代碼

image.png

而後繼續執行測試方法、結果發現執行了三次,而後輸出請求失敗語句。

image.png

可是隻是這樣並不知足咱們實際業務,在實際業務中若是超太重試以後,通常須要記錄本次失敗緣由,而且調用補償方法進行業務處理,與消息推送,因此咱們可使用@Recover註解來實現超出重試次數後執行補償方法。

image.png

可是這裏須要注意的是,@Recover聲明的方法必須與@Retryable聲明的方法返回值一致,否則補償方法會不生效。

如下是Spring自動重試註解的說明

@Retryable註解中的參數說明:

maxAttempts :最大重試次數,默認爲3,若是要設置的重試次數爲3,能夠不寫;
value:拋出指定異常纔會重試
include:和value同樣,默認爲空,當exclude也爲空時,默認因此異常
exclude:指定不處理的異常
backoff:重試等待策略,默認使用@Backoff@Backoff的value默認爲1000L,咱們設置爲2000L。

@Backoff註解中的參數說明:

value:隔多少毫秒後重試,默認爲1000L,咱們設置爲3000L;
delay:和value同樣,可是默認爲0;
multiplier(指定延遲倍數)默認爲0,表示固定暫停1秒後進行重試,若是把multiplier設置爲1.5,
則第一次重試爲2秒,第二次爲3秒,第三次爲4.5秒。
複製代碼

若是對您有幫助 請點個關注,萬分感謝

相關文章
相關標籤/搜索