SpringBoot中使用spring-retry 解決失敗重試調(diào)用
在日常開發(fā)過(guò)程中,難免會(huì)與第三方接口發(fā)生交互,例如:短信發(fā)送、遠(yuǎn)程服務(wù)調(diào)用、爭(zhēng)搶鎖等場(chǎng)景,當(dāng)正常調(diào)用發(fā)生異常時(shí),例如:網(wǎng)絡(luò)抖動(dòng),這些間歇性的異常在一段時(shí)候之后會(huì)自行恢復(fù),程序?yàn)榱烁咏巡⑶腋蝗菀壮霈F(xiàn)故障,需要重新觸發(fā)業(yè)務(wù)操作,以防止間歇性的異常對(duì)程序照成的影響。
常用的重試策略,比如通過(guò) while 循環(huán)手動(dòng)重復(fù)調(diào)用或是通過(guò) JDK/CGLib 動(dòng)態(tài)代理的方式來(lái)進(jìn)行重試。但是這種方法比較笨重,且對(duì)原有邏輯代碼的入侵性比較大。
1、引入spring-retry
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> </dependency>
這里我們還引入了 aop 的依賴,因?yàn)?spring-retry 的原理就是基于 aop 來(lái)實(shí)現(xiàn)的
2、開啟spring-retry
啟動(dòng)類上增加注解 @EnableRetry
@EnableRetry @SpringBootApplication public class AsurplusApplication { public static void main(String[] args) { SpringApplication.run(AsurplusApplication.class, args); } }
3、@Retryable
在需要重試的方法上增加注解 @Retryable,表示該方法需要重試
@Component public class TestRetry { int a = 0; @Retryable(value = {RuntimeException.class}, maxAttempts = 5, backoff = @Backoff(delay = 1000, multiplier = 2)) public String test() { a++; System.out.println(a + " - " + System.currentTimeMillis()); if (a < 10) { throw new RuntimeException("未滿足條件"); } return "執(zhí)行成功"; } }
@Retryable 注解
- value,可重試的異常類型。含義同include。默認(rèn)為空(如果excludes也為空,則重試所有異常)
- include:可重試的異常類型。默認(rèn)為空(如果excludes也為空,則重試所有異常)
- exclude:無(wú)需重試的異常類型。默認(rèn)為空(如果includes也為空,則重試所有異常)
- maxAttempts:最大重試次數(shù)(包括第一次失敗),默認(rèn)為3次
- backoff:重試等待策略,下面會(huì)在@Backoff中介紹
- recover:表示重試次數(shù)到達(dá)最大重試次數(shù)后的回調(diào)方法
@Backoff 注解
- delay,重試之間的等待時(shí)間(以毫秒為單位)
- maxDelay,重試之間的最大等待時(shí)間(以毫秒為單位)
- multiplier,指定延遲的倍數(shù)
- delayExpression,重試之間的等待時(shí)間表達(dá)式
- maxDelayExpression,重試之間的最大等待時(shí)間表達(dá)式
- multiplierExpression,指定延遲的倍數(shù)表達(dá)式
- random,隨機(jī)指定延遲時(shí)間
4、重試耗盡
當(dāng)重試耗盡時(shí),RetryOperations 可以將控制傳遞給另一個(gè)回調(diào),即 RecoveryCallback。Spring-Retry 還提供了 @Recover 注解,用于 @Retryable 重試失敗后處理方法。若不需要重試失敗后的處理方法,則不寫回調(diào)方法,重試耗盡后拋出異常。
@Recover public String recoverTest(RuntimeException e) { return "回調(diào)方法-" + e.getMessage(); }
- 方法的返回值必須與 @Retryable 方法一致
- 方法的第一個(gè)參數(shù),必須是 Throwable 類型的,建議是與 @Retryable 配置的異常一致,其他的參數(shù),需要哪個(gè)參數(shù),寫進(jìn)去就可以了(@Recover 方法中有的)
- 該回調(diào)方法與重試方法寫在同一個(gè)實(shí)現(xiàn)類里面
若同一個(gè)實(shí)現(xiàn)類中有多個(gè)回調(diào)方法,我們需要使用 recover 屬性指定回調(diào)的方法名
@Component public class TestRetry { int a = 0; @Retryable(recover = "recoverTest1", value = {RuntimeException.class}, maxAttempts = 5, backoff = @Backoff(delay = 1000, multiplier = 2)) public String test() { a++; System.out.println(a + " - " + System.currentTimeMillis()); if (a < 10) { throw new RuntimeException("未滿足條件"); } return "執(zhí)行成功"; } @Recover public String recoverTest(RuntimeException e) { return "回調(diào)方法-" + e.getMessage(); } @Recover public String recoverTest1(RuntimeException e) { return "回調(diào)方法1-" + e.getMessage(); } }
指定了回調(diào)方法為 recoverTest1
5、注意事項(xiàng)
由于是基于 AOP 實(shí)現(xiàn),所以不支持類里自調(diào)用方法
如果重試失敗需要給 @Recover 注解的方法做后續(xù)處理,那這個(gè)重試的方法不能有返回值,只能是 void
方法內(nèi)不能使用 try catch,只能往外拋異常
@Recover 注解來(lái)開啟重試失敗后調(diào)用的方法(注意,需跟重處理方法在同一個(gè)類中),此注解注釋的方法參數(shù)一定要是 @Retryable 拋出的異常,否則無(wú)法識(shí)別,可以在該方法中進(jìn)行日志處理。
到此這篇關(guān)于SpringBoot中使用spring-retry 解決失敗重試調(diào)用的文章就介紹到這了,更多相關(guān)SpringBoot spring-retry失敗重試內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot使用spring retry重試機(jī)制的操作詳解
- Java中使用Spring Retry實(shí)現(xiàn)重試機(jī)制的流程步驟
- spring @retryable不生效的一種場(chǎng)景分析
- 重試框架Guava-Retry和spring-Retry的使用示例
- Spring-Retry(重試機(jī)制)解讀
- Spring-retry實(shí)現(xiàn)循環(huán)重試功能
- spring-retry組件的使用教程
- Spring @Retryable注解輕松搞定循環(huán)重試功能
- Spring?Retry?實(shí)現(xiàn)樂(lè)觀鎖重試實(shí)踐記錄
相關(guān)文章
JDK動(dòng)態(tài)代理之WeakCache緩存的實(shí)現(xiàn)機(jī)制
這篇文章主要介紹了JDK動(dòng)態(tài)代理之WeakCache緩存的實(shí)現(xiàn)機(jī)制2018-02-02java原裝代碼完成pdf在線預(yù)覽和pdf打印及下載
本文主要介紹了java原裝代碼完成pdf在線預(yù)覽和pdf打印及下載的方法,具有一定的參考價(jià)值,下面跟著小編一起來(lái)看下吧2017-02-02SpringBoot 2 統(tǒng)一異常處理過(guò)程解析
這篇文章主要介紹了SpringBoot 2 統(tǒng)一異常處理過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09Springboot的ThreadPoolTaskScheduler線程池輕松搞定15分鐘不操作自動(dòng)取消訂單
這篇文章主要介紹了Springboot的ThreadPoolTaskScheduler線程池輕松搞定15分鐘不操作自動(dòng)取消訂單,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下2025-01-01java編程無(wú)向圖結(jié)構(gòu)的存儲(chǔ)及DFS操作代碼詳解
這篇文章主要介紹了java編程無(wú)向圖結(jié)構(gòu)的存儲(chǔ)及DFS操作代碼詳解,具有一定借鑒價(jià)值,需要的朋友可以了解下。2017-12-12詳細(xì)解讀AbstractStringBuilder類源碼
這篇文章主要介紹了詳細(xì)解讀AbstractStringBuilder類源碼,具有一定參考價(jià)值,需要的朋友可以了解下。2017-12-12jpa實(shí)現(xiàn)多對(duì)多的屬性時(shí)查詢的兩種方法
這篇文章主要介紹了jpa實(shí)現(xiàn)多對(duì)多的屬性時(shí)查詢的兩種方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11Java中ShardingSphere 數(shù)據(jù)分片的實(shí)現(xiàn)
其實(shí)很多人對(duì)分庫(kù)分表多少都有點(diǎn)恐懼,我們今天用ShardingSphere 給大家演示數(shù)據(jù)分片,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09