Spring中的retry重試組件詳解
一、簡介
Spring-retry 前面我們了解到了,Guava的重試組件,我們可以基于Guava的能力,來封裝我們需要的能力來滿足我們的業(yè)務(wù)。
今天來分享Spring-Retry重試組件。當然Spring只是幫我們封裝好了,如果你不想自定義 重試組件,那么我們可以直接使用Spring的能力來實現(xiàn)。
API 也是非常的簡單,幾個注解就可以搞定。
二、依賴
<!--springboot項目都不用引入版本號-->
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
<!--還是需要aop的支持的(如果已經(jīng)引入了aop就不用再添加這個依賴了)-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency>三、使用
3.1 @EnableRetry 開啟重試
SpringBoot啟動類上添加開啟重試注解
@EnableRetry
@SpringBootApplication
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = SpringApplication.run(Application.class, args);
}
}3.2 @Retryable 重試策略
在需要重試的方法上加注解@Retryable
@Retryable(value = RuntimeException.class, maxAttempts = 5, backoff = @Backoff(delay = 100))
public String say(String param) {
double random = Math.random();
if (random > 0.1) {
throw new RuntimeException("超時");
}
return random + "";
}- value = RuntimeException.class:是指方法拋出RuntimeException異常時,進行重試。這里可以指定你想要攔截的異常。
- maxAttempts:是最大重試次數(shù)。如果不寫,則是默認3次。
- backoff = @Backoff(delay = 100):是指重試間隔。delay=100意味著下一次的重試,要等100毫秒之后才能執(zhí)行。
3.3 @Recover 重試失敗
當@Retryable方法重試失敗之后,最后就會調(diào)用@Recover方法。用于@Retryable失敗時的“兜底”處理方法。 @Recover的方法必須要與@Retryable注解的方法保持一致,第一入?yún)橐卦嚨漠惓?,其他參?shù)與@Retryable保持一致,返回值也要一樣,否則無法執(zhí)行!
@Retryable(value = IllegalAccessException.class)
public void say() throws IllegalAccessException {
log.info("do something... {}", LocalDateTime.now());
throw new IllegalAccessException();
}
@Recover
public void sayBackup(IllegalAccessException e) {
log.info("service retry after Recover => {}", e.getMessage());
}3.4 @CircuitBreaker 熔斷策略
規(guī)定時間內(nèi)如果重試次數(shù)達到了最大次數(shù),開啟熔斷策略。 5秒內(nèi),這個方法重試了2次,就會斷路。直接走@Recover修飾的方法。當超過10s后進行重置,繼續(xù)走get方法。
注意@Retryable和@CircuitBreaker不要修飾同一個方法。
@CircuitBreaker(openTimeout = 5000, maxAttempts = 2,resetTimeout = 10000)
public String get(@PathVariable Integer flag) {
if (flag > 1) {
log.info("重試進入");
throw new RuntimeException("自定義異常");
}
return "處理正常";
}
@Recover
public String getBackup(RuntimeException runtimeException) {
log.error("重試一直失敗,進入備用方法:" + runtimeException.getMessage());
return "備用方法進去";
}| 屬性 | 說明 |
| include | 指定處理的異常類。默認為空 |
| exclude | 指定不需要處理的異常。默認為空 |
| value | 指定要重試的異常。默認為空 |
| maxAttempts | 最大重試次數(shù)。默認3次 |
| openTimeout | 配置熔斷器打開的超時時間,默認5s,當超過openTimeout之后熔斷器電路變成半打開狀態(tài)(只要有一次重試成功,則閉合電路) |
| resetTimeout | 配置熔斷器重新閉合的超時時間,默認20s,超過這個時間斷路器關(guān)閉 |
| include | 指定處理的異常類。默認為空 |
3.5 RetryListener 監(jiān)聽器
spring-retry和guava-retry一樣同樣有監(jiān)聽器。我們可以自定義我們的監(jiān)聽器
@Slf4j
public class DefaultListenerSupport extends RetryListenerSupport {
@Override
public <T, E extends Throwable> void close(RetryContext context,
RetryCallback<T, E> callback, Throwable throwable) {
log.info("onClose");
super.close(context, callback, throwable);
}
@Override
public <T, E extends Throwable> void onError(RetryContext context,
RetryCallback<T, E> callback, Throwable throwable) {
log.info("onError");
super.onError(context, callback, throwable);
}
@Override
public <T, E extends Throwable> boolean open(RetryContext context,
RetryCallback<T, E> callback) {
log.info("onOpen");
return super.open(context, callback);
}
}
@Configuration
public class RetryConfig {
@Bean
public RetryTemplate retryTemplate() {
RetryTemplate retryTemplate = new RetryTemplate();
SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy(); //設(shè)置重試策略
retryPolicy.setMaxAttempts(2);
retryTemplate.setRetryPolicy(retryPolicy);
FixedBackOffPolicy fixedBackOffPolicy = new FixedBackOffPolicy(); //設(shè)置退避策略
fixedBackOffPolicy.setBackOffPeriod(2000L);
retryTemplate.setBackOffPolicy(fixedBackOffPolicy);
retryTemplate.registerListener(new DefaultListenerSupport()); //設(shè)置retryListener
return retryTemplate;
}
}3.6 RetryPolicy 重試策略
| 屬性 | 說明 |
| NeverRetryPolicy | 只允許調(diào)用RetryCallback一次,不允許重試; |
| AlwaysRetryPolicy | 允許無限重試,直到成功,此方式邏輯不當會導致死循環(huán); |
| SimpleRetryPolicy | 固定次數(shù)重試策略,默認重試最大次數(shù)為3次,RetryTemplate默認使用的策略; |
| TimeoutRetryPolicy | 超時時間重試策略,默認超時時間為1秒,在指定的超時時間內(nèi)允許重試; |
| CircuitBreakerRetryPolicy | 有熔斷功能的重試策略,需設(shè)置3個參數(shù)openTimeout、resetTimeout和delegate |
| CompositeRetryPolicy | 組合重試策略,有兩種組合方式,樂觀組合重試策略是指只要有一個策略允許重試即可以,悲觀組合重試策略是指只要有一個策略不允許重試即可以,但不管哪種組合方式,組合中的每一個策略都會執(zhí)行。 |
3.7 BackOffPolicy 退避策略
下一次重試的策略。 退避是指怎么去做下一次的重試,在這里其實就是等待多長時間。
| 屬性 | 說明 |
| FixedBackOffPolicy | 默認固定延遲1秒后執(zhí)行下一次重試 |
| ExponentialBackOffPolicy | 指數(shù)遞增延遲執(zhí)行重試,默認初始0.1秒,系數(shù)是2,那么下次延遲0.2秒,再下次就是延遲0.4秒,如此類推,最大30秒。 |
| ExponentialRandomBackOffPolicy | 在上面那個策略上增加隨機性 |
| UniformRandomBackOffPolicy | 這個跟上面的區(qū)別就是,上面的延遲會不停遞增,這個只會在固定的區(qū)間隨機 |
| StatelessBackOffPolicy | 這個說明是無狀態(tài)的,所謂無狀態(tài)就是對上次的退避無感知,從它下面的子類也能看出來 |
四、總結(jié)
天下代碼一大抄,看你會抄不會抄。發(fā)現(xiàn)無論是guava還是spring的重試,基本都是類似的思路。只是看誰的功能比較鑒權(quán)而已。 guava提供了基礎(chǔ)的能力,你任意封裝。 spring基于spring提供了已經(jīng)完好的能力,直接使用就好。不過因為是spring給你封裝的能力,所以你要先了解清楚才行。不然可能使用錯誤,造成故障。
以上兩款工具都挺好,不過他們都不支持分布式重試的能力。不過這已經(jīng)滿足我們的日常開發(fā)了,如果真遇到分布式的重試,就自己來實現(xiàn)咯。
到此這篇關(guān)于Spring中的retry重試組件詳解的文章就介紹到這了,更多相關(guān)retry重試組件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring?Boot集成LiteFlow規(guī)則引擎的詳細過程
本文詳細介紹了如何在Spring?Boot應(yīng)用程序中集成LiteFlow規(guī)則引擎,并探討如何使用LiteFlow庫來實現(xiàn)業(yè)務(wù)流程的規(guī)則處理,將通過具體的示例來展示如何在Spring?Boot應(yīng)用程序中配置和使用LiteFlow規(guī)則引擎,以提高系統(tǒng)的靈活性和可維護性,感興趣的朋友跟隨小編一起看看吧2024-07-07
Java使用Hutool+自定義注解實現(xiàn)數(shù)據(jù)脫敏
我們在使用手機銀行的時候經(jīng)常能看到APP上會將銀行卡的卡號中間部分給隱藏掉使用 ***** 來代替,在某些網(wǎng)站上查看一些業(yè)務(wù)密碼時(例如簽到密碼等)也會使用 ***** 來隱藏掉真正的密碼,那么這種方式是如何實現(xiàn)的呢,本文將給大家介紹使用Hutool+自定義注解實現(xiàn)數(shù)據(jù)脫敏2023-09-09
Mybatis-Plus同時使用邏輯刪除和唯一索引的問題及解決辦法(報數(shù)據(jù)重復Duplicate entry的
在開發(fā)中,我們經(jīng)常會有邏輯刪除和唯一索引同時使用的情況,但當使用mybatis plus時,如果同時使用邏輯刪除和唯一索引,會報數(shù)據(jù)重復Duplicate entry的問題,如何解決這個問題呢,小編給大家分享Mybatis-Plus同時使用邏輯刪除和唯一索引的問題及解決辦法,一起看看吧2023-11-11
Java循環(huán)調(diào)用多個timer實現(xiàn)定時任務(wù)
這篇文章主要介紹了Java循環(huán)調(diào)用多個timer實現(xiàn)定時任務(wù),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-07-07
Java多線程之synchronized關(guān)鍵字的使用
這篇文章主要介紹了Java多線程之synchronized關(guān)鍵字的使用,文中有非常詳細的代碼示例,對正在學習java的小伙伴們有非常好的幫助,需要的朋友可以參考下2021-04-04
Mybatis-Plus的應(yīng)用場景描述及注入SQL原理分析
MyBatis-Plus是一個 MyBatis 的增強工具,在 MyBatis 的基礎(chǔ)上只做增強不做改變,為簡化開發(fā)、提高效率而生,本文重點給大家介紹Mybatis-Plus的應(yīng)用場景及注入SQL原理分析,感興趣的朋友跟隨小編一起學習吧2021-05-05
Java String 和StringBuffer的詳解及區(qū)別
這篇文章主要介紹了Java String 和StringBuffer的詳解及區(qū)別的相關(guān)資料,需要的朋友可以參考下2017-05-05

