spring?retry實(shí)現(xiàn)方法請(qǐng)求重試的使用步驟
1 spring-retry是什么?
以往我們在進(jìn)行網(wǎng)絡(luò)請(qǐng)求的時(shí)候,需要考慮網(wǎng)絡(luò)異常的情況,本文就介紹了利用spring-retry,是spring提供的一個(gè)重試框架,原本自己實(shí)現(xiàn)的重試機(jī)制,現(xiàn)在spring幫封裝好提供更加好的編碼體驗(yàn)。
2 使用步驟
2.1 引入maven庫
代碼如下(示例):
<dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>4.3.9.RELEASE</version> </dependency>
2.2 在spring啟動(dòng)類上開啟重試功能
提示:添加@EnableRetry注解開啟 @SpringBootApplication @EnableRetry public class SpringRetryDemoApplication { public static SpringRetryAnnotationService springRetryAnnotationService; public static SpringRetryImperativeService springRetryImperativeService; public static TranditionalRetryService tranditionalRetryService; @Autowired public void setSpringRetryAnnotationService(SpringRetryAnnotationService springRetryAnnotationService) { SpringRetryDemoApplication.springRetryAnnotationService = springRetryAnnotationService; } @Autowired public void setSpringRetryImperativeService(SpringRetryImperativeService springRetryImperativeService) { SpringRetryDemoApplication.springRetryImperativeService = springRetryImperativeService; } @Autowired public void setTranditionalRetryService(TranditionalRetryService tranditionalRetryService) { SpringRetryDemoApplication.tranditionalRetryService = tranditionalRetryService; } public static void main(String[] args) { SpringApplication.run(SpringRetryDemoApplication.class, args); springRetryAnnotationService.test(); springRetryImperativeService.test(); tranditionalRetryService.test(); } }
2.3 公共業(yè)務(wù)代碼
@Service @Slf4j public class CommonService { public void test(String before) { for (int i = 0; i < 10; i++) { if (i == 2) { log.error("{}:有異常哦,我再試多幾次看下還有沒異常", before); throw new RuntimeException(); } log.info("{}:打印次數(shù): {}", before, i + 1); } } public void recover(String before) { log.error("{}:還是有異常,程序有bug哦", before); } }
2.4 傳統(tǒng)的重試做法
@Service @Slf4j public class TranditionalRetryService { @Autowired CommonService commonService; public void test() { // 定義重試次數(shù)以及重試時(shí)間間隔 int retryCount = 3; int retryTimeInterval = 3; for (int r = 0; r < retryCount; r++) { try { commonService.test("以前的做法"); } catch (RuntimeException e) { if (r == retryCount - 1) { commonService.recover("以前的做法"); return; } try { Thread.sleep(retryTimeInterval * 1000); } catch (InterruptedException ex) { ex.printStackTrace(); } } } } }
2.5 使用spring-retry的命令式編碼
2.5.1 定義重試監(jiān)聽器
提示:監(jiān)聽重試過程的生命周期 @Slf4j public class MyRetryListener extends RetryListenerSupport { @Override public <T, E extends Throwable> void close(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) { log.info("監(jiān)聽到重試過程關(guān)閉了"); log.info("======================================================================="); } @Override public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) { log.info("監(jiān)聽到重試過程錯(cuò)誤了"); } @Override public <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback) { log.info("======================================================================="); log.info("監(jiān)聽到重試過程開啟了"); return true; } }
2.5.2 定義重試配置
提示:配置RetryTemplate重試模板類 @Configuration public class RetryConfig { @Bean public RetryTemplate retryTemplate() { // 定義簡易重試策略,最大重試次數(shù)為3次,重試間隔為3s RetryTemplate retryTemplate = RetryTemplate.builder() .maxAttempts(3) .fixedBackoff(3000) .retryOn(RuntimeException.class) .build(); retryTemplate.registerListener(new MyRetryListener()); return retryTemplate; } }
2.5.3 命令式編碼
@Service @Slf4j public class SpringRetryImperativeService { @Autowired RetryTemplate retryTemplate; @Autowired CommonService commonService; public void test() { retryTemplate.execute( retry -> { commonService.test("命令式"); return null; }, recovery -> { commonService.recover("命令式"); return null; } ); } }
2.6使用spring-retry的注解式編碼
@Service @Slf4j public class SpringRetryAnnotationService { @Autowired CommonService commonService; /** * 如果失敗,定義重試3次,重試間隔為3s,指定恢復(fù)名稱,指定監(jiān)聽器 */ @Retryable(value = RuntimeException.class, maxAttempts = 3, backoff = @Backoff(value = 3000L), recover = "testRecover", listeners = {"myRetryListener"}) public void test() { commonService.test("注解式"); } @Recover public void testRecover(RuntimeException runtimeException) { commonService.recover("注解式"); } }
3 SpringBoot整合spring-retry
我們使用SpringBoot來整合spring-retry組件實(shí)現(xiàn)重試機(jī)制。
3.1 添加@EnableRetry注解
在主啟動(dòng)類Application上添加@EnableRetry注解,實(shí)現(xiàn)對(duì)重試機(jī)制的支持
@SpringBootApplication @EnableRetry public class RetryApplication { public static void main(String[] args) { SpringApplication.run(RetryApplication.class, args); } }
注意:@EnableRetry也可以使用在配置類、ServiceImpl類、方法上
3.2 接口實(shí)現(xiàn)
注意:接口類一定不能少,在接口類中定義你需要實(shí)現(xiàn)重試的方法,否則可能會(huì)無法實(shí)現(xiàn)重試功能
我的測試接口類如下:
public interface RetryService { public String testRetry() throws Exception;}
3.3 添加@Retryable注解
我們針對(duì)需要實(shí)現(xiàn)重試的方法上添加@Retryable
注解,使該方法可以實(shí)現(xiàn)重試,這里我列出ServiceImpl
中的一個(gè)方法:
@Service public class RetryServiceImpl implements RetryService { @Override @Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 2000,multiplier = 1.5)) public String testRetry() throws Exception { System.out.println("開始執(zhí)行代碼:"+ LocalTime.now()); int code = 0; // 模擬一直失敗 if(code == 0){ // 這里可以使自定義異常,@Retryable中value需與其一致 throw new Exception("代碼執(zhí)行異常"); } System.out.println("代碼執(zhí)行成功"); return "success"; } }
說明:@Retryable配置元數(shù)據(jù)情況:
value :針對(duì)指定拋出的異常類型,進(jìn)行重試,這里指定的是Exception
maxAttempts :配置最大重試次數(shù),這里配置為3次(包含第一次和最后一次)
delay: 第一次重試延遲間隔,這里配置的是2s
multiplier :每次重試時(shí)間間隔是前一次幾倍,這里是1.5倍
3.4 Controller測試代碼
@RestController @RequestMapping("/test") public class TestController { // 一定要注入接口,通過接口去調(diào)用方法 @Autowired private RetryService retryService; @GetMapping("/retry") public String testRetry() throws Exception { return retryService.testRetry(); } }
3.5 發(fā)送請(qǐng)求
發(fā)送請(qǐng)求后,我們發(fā)現(xiàn)后臺(tái)打印情況,確實(shí)重試了3次,并且在最后一次重試失敗的情況下,才拋出異常,具體如下(可以注意下時(shí)間間隔)
3.6 補(bǔ)充:@Recover
一般情況下,我們重試最大設(shè)置的次數(shù)后,仍然失敗拋出異常,我們會(huì)通過全局異常處理類進(jìn)行統(tǒng)一處理,但是我們其實(shí)也可以自行處理,可以通過@Recover
注解來實(shí)現(xiàn),具體如下:
@Service public class RetryServiceImpl implements RetryService { @Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 2000,multiplier = 1.5)) public String testRetry() throws Exception { System.out.println("開始執(zhí)行代碼:"+ LocalTime.now()); int code = 0; if(code == 0){ // 這里可以使自定義異常,@Retryable中value需與其一致 throw new Exception("代碼執(zhí)行異常"); } System.out.println("代碼執(zhí)行成功"); return "success"; } /** * 最終重試失敗處理 * @param e * @return */ @Recover public String recover(Exception e){ System.out.println("代碼執(zhí)行重試后依舊失敗"); return "fail"; } }
注意:
1)@Recover的方法中的參數(shù)異常類型需要與重試方法中一致
2)該方法的返回值類型與重試方法保持一致
再次測試如下(發(fā)現(xiàn)不會(huì)再拋出異常)
到此這篇關(guān)于spring retry實(shí)現(xiàn)方法請(qǐng)求重試的文章就介紹到這了,更多相關(guān)spring retry方法請(qǐng)求重試內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot實(shí)現(xiàn)HTTP服務(wù)監(jiān)聽的代碼示例
前后端分離項(xiàng)目中,在調(diào)用接口調(diào)試時(shí)候,我們可以通過cpolar內(nèi)網(wǎng)穿透將本地服務(wù)端接口模擬公共網(wǎng)絡(luò)環(huán)境遠(yuǎn)程調(diào)用調(diào)試,本次教程我們以Java服務(wù)端接口為例,需要的朋友可以參考下2023-05-05java isInterrupted()判斷線程的實(shí)例講解
在本篇內(nèi)容里小編給大家分享的是一篇關(guān)于java isInterrupted()判斷線程的實(shí)例講解內(nèi)容,有興趣的朋友們可以學(xué)習(xí)下。2021-05-05java中String與StringBuilder的區(qū)別
本篇文章介紹了,java中String與StringBuilder的區(qū)別。需要的朋友參考下2013-04-04Java基于中介者模式實(shí)現(xiàn)多人聊天室功能示例
這篇文章主要介紹了Java基于中介者模式實(shí)現(xiàn)多人聊天室功能,詳細(xì)分析了中介者模式的概念、原理以及使用中介模式實(shí)現(xiàn)多人聊天的步驟、操作技巧與注意事項(xiàng),需要的朋友可以參考下2018-05-05Spring注解驅(qū)動(dòng)之BeanPostProcessor后置處理器講解
這篇文章主要介紹了Spring注解驅(qū)動(dòng)之BeanPostProcessor后置處理器講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09