背景: 在實際項目中,咱們在與其餘第三方業務接口進行交互時,可能會由於一些網絡波動致使超時失敗,可是並不能只一次失敗就斷定接口請求失敗,應該考慮重試屢次後若是仍然失敗,才返回請求失敗。spring
解決方案:markdown
解決方案一:try-catch 簡單重試網絡
經過判斷返回結果或監聽異常斷定是否重試,同時爲了解決當即重試的無效執行(假設異常是有外部執行不穩定致使的),休眠必定延遲時間從新執行功能邏輯。測試
可是這樣會存在一個問題,那就是若是是請求參數不正常,那麼就會一直重試下去,變成了死循環。spa
這樣確定不是咱們想要的解決方案,因此咱們須要添加限制,判斷重試多少次之後仍然失敗,就返回失敗結果。3d
而後此次再看執行結果,此次就按照咱們設置的次數進行重試了,已經達到了業務需求code
結論: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))
複製代碼
而後繼續執行測試方法、結果發現執行了三次,而後輸出請求失敗語句。
可是隻是這樣並不知足咱們實際業務,在實際業務中若是超太重試以後,通常須要記錄本次失敗緣由,而且調用補償方法進行業務處理,與消息推送,因此咱們可使用@Recover註解來實現超出重試次數後執行補償方法。
可是這裏須要注意的是,@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秒。
複製代碼
若是對您有幫助 請點個關注,萬分感謝