Spring中的spring-retry重試機(jī)制解析
spring-retey的依賴
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>1.3.1</version>
</dependency>spring-retry無注解方式使用
定義重試任務(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("收到請求參數(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)程訪問異常");
}
}
}構(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 允許無限重試,直到成功,此方式邏輯不當(dāng)會導(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種組合方式,樂觀組合重試策略是指只要有一個(gè)策略允許即可以重試,
* 悲觀組合重試策略是指只要有一個(gè)策略不允許即可以重試,但不管哪種組合方式,組合中的每一個(gè)策略都會執(zhí)行
*
* spring-retry支持的重試回退策略有
*
* NoBackOffPolicy:無退避算法策略,每次重試時(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("收到請求參數(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)程訪問異常");
}
}
}定義重試服務(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è)沒有指定進(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)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
jstack+jdb命令查看線程及死鎖堆棧信息的實(shí)例
這篇文章主要介紹了jstack+jdb命令查看線程及死鎖堆棧信息的實(shí)例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-02-02
Scheduler定時(shí)任務(wù)調(diào)度詳解
文章介紹了SysJobServiceImpl類中定時(shí)任務(wù)調(diào)度的相關(guān)方法,包括清除、檢查存在性、創(chuàng)建、暫停、恢復(fù)、刪除任務(wù),以及觸發(fā)任務(wù),并提到了JobKey、CronUtils、ScheduleUtils、SpringUtils等工具類的使用,適用于Spring管理環(huán)境2025-01-01
Java高級開發(fā)高頻面試題完整版(由淺入深&高薪必背)
Java是一個(gè)支持并發(fā)、基于類和面向?qū)ο蟮挠?jì)算機(jī)編程語言,這篇文章主要介紹了Java高級開發(fā)高頻面試題的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2026-03-03
SpringBoot+Thymeleaf+ECharts實(shí)現(xiàn)大數(shù)據(jù)可視化(基礎(chǔ)篇)
本文主要介紹了SpringBoot+Thymeleaf+ECharts實(shí)現(xiàn)大數(shù)據(jù)可視化,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧<BR>2022-06-06
深入理解Java運(yùn)行時(shí)數(shù)據(jù)區(qū)_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了Java運(yùn)行時(shí)數(shù)據(jù)區(qū)的相關(guān)知識,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧2017-06-06
關(guān)于@Qualifier("beanName")用法
@Qualifier用于精確指定Bean,@Primary設(shè)為默認(rèn),兩者共存時(shí),@Qualifier優(yōu)先級更高,可靈活選擇具體實(shí)現(xiàn),解決依賴注入歧義,兼顧簡潔與可配置性2025-09-09

