使用Spring-Retry解決Spring Boot應(yīng)用程序中的重試問題
1、背景
在日常開發(fā)過程中,難免會(huì)與第三方接口發(fā)生交互,例如:遠(yuǎn)程服務(wù)調(diào)用當(dāng)正常調(diào)用發(fā)生異常時(shí),例如:網(wǎng)絡(luò)抖動(dòng)等短時(shí)間內(nèi)的臨時(shí)問題,程序?yàn)榱烁咏巡⑶腋蝗菀壮霈F(xiàn)故障。需要重新觸發(fā)業(yè)務(wù)操作,以防止間歇性的異常對(duì)程序照成的影響。這個(gè)可以就可以用重試來解決。
2、引入依賴
<!--因?yàn)閟pring-retry是基于aop實(shí)現(xiàn),所以需要引入aop--> <dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
3、開啟spring-retry
在springboot的啟動(dòng)類上增加注解 @EnableRetry
@EnableRetry
@SpringBootApplication
public class RetryApplication {
public static void main(String[] args) {
SpringApplication.run(RetryApplication.class, args);
}
}
4、在方法上添加@Retryable
@Component
public class TestRetry {
/**
* value:拋出指定異常才會(huì)重試
* include:和value一樣,默認(rèn)為空,當(dāng)exclude也為空時(shí),默認(rèn)所有異常
* exclude:指定不處理的異常
* maxAttempts:最大重試次數(shù),默認(rèn)3次
* backoff:重試等待策略,
* 默認(rèn)使用@Backoff,@Backoff的value默認(rèn)為1000L,我們?cè)O(shè)置為2000; 以毫秒為單位的延遲(默認(rèn) 1000)
* multiplier(指定延遲倍數(shù))默認(rèn)為0,表示固定暫停1秒后進(jìn)行重試,如果把multiplier設(shè)置為1.5,則第一次重試為2秒,第二次為3秒,第三次為4.5秒。
* @param code
* @return
* @throws Exception
*/
@Retryable(value = Exception.class,maxAttempts = 3,backoff = @Backoff(delay = 2000,multiplier = 1.5))
public int testRetry(int code) throws Exception{
System.out.println("test被調(diào)用,時(shí)間:"+ LocalTime.now());
if (code==0){
throw new Exception("調(diào)用失敗!");
}
System.out.println("test被調(diào)用!");
return 200;
}
}
@Retryable 注解
value,可重試的異常類型。含義同include。默認(rèn)為空(如果excludes也為空,則重試所有異常)
include:可重試的異常類型。默認(rèn)為空(如果excludes也為空,則重試所有異常)
exclude:無需重試的異常類型。默認(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í)間
5、重試完
當(dāng)重試完,RetryOperations 可以將控制傳遞給另一個(gè)回調(diào),即 RecoveryCallback。Spring-Retry 還提供了 @Recover 注解,用于 @Retryable 重試失敗后處理方法。若不需要重試失敗后的處理方法,則不寫回調(diào)方法,重試耗盡后拋出異常。
@Component
public class TestRetry {
@Retryable(recover = "recoverTest",value = Exception.class,maxAttempts = 3,backoff = @Backoff(delay = 2000,multiplier = 1.5))
public int testRetry(int code) throws Exception{
System.out.println("test被調(diào)用,時(shí)間:"+ LocalTime.now());
if (code==0){
throw new Exception("調(diào)用失敗!");
}
System.out.println("test被調(diào)用!");
return 200;
}
/**
**方法的返回值必須與 @Retryable 方法一致
**方法的第一個(gè)參數(shù),必須是 Throwable 類型的,建議是與 @Retryable 配置的**異常一致,其他的參數(shù),需要哪個(gè)參數(shù),寫進(jìn)去就可以了(@Recover 方法中有的)
**該回調(diào)方法與重試方法寫在同一個(gè)實(shí)現(xiàn)類里面
*/
@Recover
public String recoverTest(RuntimeException e) {
return "回調(diào)方法-" + e.getMessage();
}
}6、注意事項(xiàng)
由于是基于 AOP 實(shí)現(xiàn),所以不支持類里自調(diào)用方法
如果重試失敗需要給 @Recover 注解的方法做后續(xù)處理,那這個(gè)重試的方法不能有返回值,只能是 void
方法內(nèi)不能使用 try catch,只能往外拋異常
@Recover 注解來開啟重試失敗后調(diào)用的方法(注意,需跟重處理方法在同一個(gè)類中),此注解注釋的方法參數(shù)一定要是 @Retryable 拋出的異常,否則無法識(shí)別,可以在該方法中進(jìn)行日志處理。
到此這篇關(guān)于使用Spring-Retry解決Spring Boot應(yīng)用程序中的重試問題的文章就介紹到這了,更多相關(guān)Spring-Retry解決重試內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于Java創(chuàng)建線程的2種方式以及對(duì)比
這篇文章主要給大家介紹了關(guān)于Java創(chuàng)建線程的2種方式以及對(duì)比的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2022-01-01
SpringBoot關(guān)閉druid的頁面和添加密碼驗(yàn)證方式
這篇文章主要介紹了SpringBoot關(guān)閉druid的頁面和添加密碼驗(yàn)證方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05
Java實(shí)現(xiàn)Token工具類進(jìn)行登錄和攔截
在應(yīng)用的登錄時(shí)需要生成token進(jìn)行驗(yàn)證,并放入信息,之后的話可以直接使用瀏覽器的session進(jìn)行登錄,本文就來利用java編寫一個(gè)token工具類,可以很方便的生成和解析token,感興趣的可以了解下2023-12-12
如何讓java只根據(jù)數(shù)據(jù)庫(kù)表名自動(dòng)生成實(shí)體類
今天給大家?guī)淼闹R(shí)是關(guān)于Java的,文章圍繞著如何讓java只根據(jù)數(shù)據(jù)庫(kù)表名自動(dòng)生成實(shí)體類展開,文中有非常詳細(xì)的介紹,需要的朋友可以參考下2021-06-06
使用springboot aop來實(shí)現(xiàn)讀寫分離和事物配置
這篇文章主要介紹了使用springboot aop來實(shí)現(xiàn)讀寫分離和事物配置,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-04-04
探索Java中private方法添加@Transactional事務(wù)未生效原因
你又遇到過明明給private方法添加了@Transactional但是事務(wù)依然沒有生效的情況嗎,具體原因本篇文章將詳細(xì)告訴你,有需要的朋友跟著小編往下看吧2021-11-11
Java連接MySQL數(shù)據(jù)庫(kù)并實(shí)現(xiàn)數(shù)據(jù)交互的示例
數(shù)據(jù)庫(kù)是非常重要的一種存儲(chǔ)格式,可以大大提高存儲(chǔ)效率,本文主要介紹了Java連接MySQL數(shù)據(jù)庫(kù)并實(shí)現(xiàn)數(shù)據(jù)交互的示例,具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03
spring事務(wù)@Transactional失效原因及解決辦法小結(jié)
今天就跟大家聊聊有關(guān)spring中@Transactional失效原因及解決辦法小結(jié),主要從三個(gè)方面考慮,具有一定的參考價(jià)值,感興趣的可以了解一下2023-08-08

