Spring中的spring-retry重試機(jī)制解析
spring-retey的依賴(lài)
<dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> <version>1.3.1</version> </dependency>
spring-retry無(wú)注解方式使用
定義重試任務(wù)
package com.example.demo.retry; import cn.hutool.core.util.RandomUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.remoting.RemoteAccessException; @Slf4j public class RetryDemoTask { public static boolean retryTask(String param){ log.info("收到請(qǐng)求參數(shù):{}",param); int i = RandomUtil.randomInt(0,11); log.info("param - i:{}",i); if (i==0){ throw new IllegalArgumentException("參數(shù)異常"); }else if (i==1){ return true; }else if (i==2){ return false; }else { throw new RemoteAccessException("遠(yuǎn)程訪(fǎng)問(wèn)異常"); } } }
構(gòu)建重試邏輯并執(zhí)行調(diào)用
package com.example.demo; import com.example.demo.retry.RetryDemoTask; import com.example.demo.retry.SpringRetryDemo; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.remoting.RemoteAccessException; import org.springframework.retry.backoff.*; import org.springframework.retry.policy.*; import org.springframework.retry.support.RetryTemplate; import java.util.HashMap; import java.util.Map; @Slf4j @SpringBootTest public class SpringRetryTests { private long fixedPeriodTime = 1000L; private int maxRetryTimes = 3; private Map<Class<? extends Throwable>, Boolean> exceptionMap = new HashMap<>(); /** * spring-retry支持的重試策略有 * * NeverRetryPolicy 只允許retryCallback一次,不允許重試 * AlwaysRetryPolicy 允許無(wú)限重試,直到成功,此方式邏輯不當(dāng)會(huì)導(dǎo)致死循環(huán) * SimpleRetryPolicy 固定次數(shù)重試,默認(rèn)重試最大次數(shù)為3次,RetryTemplate默認(rèn)使用的策略 * TimeoutRetryPolicy 超時(shí)時(shí)間重試策略,默認(rèn)超時(shí)時(shí)間為1秒,在指定的超時(shí)時(shí)間內(nèi)允許重試 * ExceptionClassifierRetryPolicy 設(shè)置不同異常的重試策略 * CircuitBreakerRetryPolicy 有熔斷功能的重試策略,需要設(shè)置3個(gè)參數(shù)openTimeout\restTimeout和delegate * CompositeRetryPolicy: 組合重試策略,有2種組合方式,樂(lè)觀組合重試策略是指只要有一個(gè)策略允許即可以重試, * 悲觀組合重試策略是指只要有一個(gè)策略不允許即可以重試,但不管哪種組合方式,組合中的每一個(gè)策略都會(huì)執(zhí)行 * * spring-retry支持的重試回退策略有 * * NoBackOffPolicy:無(wú)退避算法策略,每次重試時(shí)立即重試 * FixedBackOffPolicy: 固定時(shí)間的退避策略,需設(shè)置參數(shù)sleeper 等待策略和backOffPeriod休眠時(shí)間,默認(rèn)1s * UniformRandomBackOffPolicy: 隨機(jī)時(shí)間退避策略,需設(shè)置sleeper\minBackOffPeriod 和 maxBackOffPeriod * ExponentialBackOffPolicy 指數(shù)退避策略,需設(shè)置sleeper\initialInterval\maxInterval等參數(shù) * ExponentialRandomBackOffPolicy 隨機(jī)指數(shù)退避策略,引入隨機(jī)乘數(shù)可以實(shí)現(xiàn)隨機(jī)乘數(shù)回退 * */ @Test void t1() { exceptionMap.put(RemoteAccessException.class, true); //構(gòu)建重試模版 RetryTemplate retryTemplate = new RetryTemplate(); //設(shè)置重試回退策略 // FixedBackOffPolicy主要設(shè)置重試間隔時(shí)間 FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy(); backOffPolicy.setBackOffPeriod(fixedPeriodTime); //設(shè)置重試策略,主要設(shè)置重試次數(shù) SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy(maxRetryTimes, exceptionMap); retryTemplate.setRetryPolicy(retryPolicy); retryTemplate.setBackOffPolicy(backOffPolicy); Boolean execute = retryTemplate.execute( //RetryCallback retryContext -> { boolean abc = RetryDemoTask.retryTask("abc"); log.info("調(diào)用的結(jié)果:{}", abc); return abc; }, //RecoveryCallback retryContext -> { log.info("已達(dá)到最大重試次數(shù)或拋出了不重試的異常..."); return false; } ); log.info("執(zhí)行結(jié)果:{}", execute); } }
spring-retry注解方式使用
啟用@EnableRetry 注解
@EnableRetry //spring-retry 基于注解的使用 @SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
定義重試任務(wù)
package com.example.demo.retry; import cn.hutool.core.util.RandomUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.remoting.RemoteAccessException; @Slf4j public class RetryDemoTask { public static boolean retryTask(String param){ log.info("收到請(qǐng)求參數(shù):{}",param); int i = RandomUtil.randomInt(0,11); log.info("param - i:{}",i); if (i==0){ throw new IllegalArgumentException("參數(shù)異常"); }else if (i==1){ return true; }else if (i==2){ return false; }else { throw new RemoteAccessException("遠(yuǎn)程訪(fǎng)問(wèn)異常"); } } }
定義重試服務(wù)層控制邏輯
package com.example.demo.retry; import lombok.extern.slf4j.Slf4j; import org.springframework.remoting.RemoteAccessException; import org.springframework.retry.annotation.Backoff; import org.springframework.retry.annotation.Recover; import org.springframework.retry.annotation.Retryable; import org.springframework.stereotype.Service; @Slf4j @Service public class SpringRetryDemoService { //發(fā)生RemoteAccessException時(shí)重試 //最大重試3次 //第一次間隔2秒,以后都是次數(shù)的2倍,也就是第二次4秒,第三次6秒 @Retryable(value = {RemoteAccessException.class}, maxAttempts = 3, backoff = @Backoff(delay = 2000L,multiplier = 2)) public boolean call(String param){ return RetryDemoTask.retryTask(param); } @Recover public boolean recover(Exception e,String param){ log.error("達(dá)到最大重試次數(shù),或拋出了一個(gè)沒(méi)有指定進(jìn)行重試的異常",e); log.info("recover param:{}",param); return false; } }
執(zhí)行重試調(diào)用
@Slf4j @SpringBootTest public class SpringRetryTests2 { @Autowired private SpringRetryDemoService springRetryDemoService; @Test public void retry712(){ boolean abc = springRetryDemoService.call("abc"); log.info("---結(jié)果是:{}---",abc); } }
到此這篇關(guān)于Spring中的spring-retry重試機(jī)制解析的文章就介紹到這了,更多相關(guān)spring-retry重試機(jī)制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue+springboot上傳文件、圖片、視頻及回顯到前端詳解
一般來(lái)說(shuō)vue可以使用axios或者fetch等ajax庫(kù)發(fā)送文件請(qǐng)求,而springboot則可以使用Spring MVC的方式來(lái)處理上傳文件請(qǐng)求,下面這篇文章主要給大家介紹了關(guān)于vue+springboot上傳文件、圖片、視頻及回顯到前端的相關(guān)資料,需要的朋友可以參考下2023-04-04SpringBoot訪(fǎng)問(wèn)接口自動(dòng)跳轉(zhuǎn)login頁(yè)面的問(wèn)題及解決
這篇文章主要介紹了SpringBoot訪(fǎng)問(wèn)接口自動(dòng)跳轉(zhuǎn)login頁(yè)面的問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12Spring MVC前后端的數(shù)據(jù)傳輸?shù)膶?shí)現(xiàn)方法
這篇文章主要介紹了Spring MVC前后端的數(shù)據(jù)傳輸?shù)膶?shí)現(xiàn)方法,需要的朋友可以參考下2017-10-10JAVA區(qū)間值判斷[10,20)的實(shí)現(xiàn)
本文主要介紹了JAVA區(qū)間值判斷[10,20)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-09-09SpringBoot中的server.context-path的實(shí)現(xiàn)
本文主要介紹了SpringBoot中的server.context-path的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-08-08解決RestTemplate 的getForEntity調(diào)用接口亂碼的問(wèn)題
這篇文章主要介紹了解決RestTemplate 的getForEntity調(diào)用接口亂碼的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08Java兩個(gè)乒乓球隊(duì)比賽名單問(wèn)題(判斷素?cái)?shù))
兩個(gè)乒乓球隊(duì)進(jìn)行比賽,各出三人。甲隊(duì)為a,b,c三人,乙隊(duì)為x,y,z三人。已抽簽決定比賽名單。有人向隊(duì)員打聽(tīng)比賽的名單。a說(shuō)他不和x比,c說(shuō)他不和x,z比,請(qǐng)編程序找出三隊(duì)賽手的名單2017-02-02springboot整合dubbo設(shè)置全局唯一ID進(jìn)行日志追蹤的示例代碼
這篇文章主要介紹了springboot整合dubbo設(shè)置全局唯一ID進(jìn)行日志追蹤,本文通過(guò)圖文示例相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10解決Maven無(wú)法下載2.1.7.js7版本的itext依賴(lài)問(wèn)題
本文主要解決使用Maven編譯項(xiàng)目時(shí)出現(xiàn)的itext依賴(lài)版本問(wèn)題,通過(guò)分析,發(fā)現(xiàn)該問(wèn)題是由jasperreports依賴(lài)的特定版本itext導(dǎo)致的,解決方法是排除jasperreports中的itext依賴(lài),并自行指定更高版本的itext依賴(lài)2024-12-12java項(xiàng)目中的多線(xiàn)程實(shí)踐記錄
項(xiàng)目開(kāi)發(fā)中對(duì)于一些數(shù)據(jù)的處理需要用到多線(xiàn)程,比如文件的批量上傳,數(shù)據(jù)庫(kù)的分批寫(xiě)入,大文件的分段下載等,主要涉及到多線(xiàn)程的一些知識(shí),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下2021-11-11