一、Spring Retry
1. 基本原理
Spring Retry是Spring提供的重试框架。作为春季生态系统的一部分,它通过AOP(面向分段的编程)实现了方法调用的重试能力。当方法调用失败时,Spring Retry会根据配置的策略自动重新执行该方法,直到成功或达到最大恢复次数为止。
春季重试的核心组成部分包括:
重试:定义重试操作的接口:重试板的默认实现重取底机:定义何时重试(例如最大次数,重试异常类型等)向后置:定义定义重试的间隔策略(例如,固定间隔,额定式恢复后恢复33)。在Springboot项目中:
依赖性groupIdorg.springframework.try/groupId artifactidspring-retry/artifactid/distionentipentys groupId.springframework/groupId framework/groupid artifactidspring-aspects/artifactid/dependent interency/dependent in and depentency,然后启用启动类别的重新启动功能:
@springbootapplication@enableRetryPublic类应用程序{public static void main(string [] args){springapplication.run(application.class,args); }}
2. 集成配置
Spring Retry提供了两种使用注释和编程的方法。
3. 使用方法
@ServicePublic类远程Ototeserviceclient {private static final logger logger=loggerfactory.getLogger(referoteserviceclient.class); @retryable(value={serviceexection.class},maxAttEmpts=3,backoff=@backoff(delays=1000,mutterner=2))public string callremoteservice(string param){logger.info(\’call remote remote Service,parameter : {}\’,param); //模拟呼叫失败,如果(Math.random()0.7){Logger.error(\’Service Call失败\’);投掷新的ServiceException(\’远程服务暂时不可用\’); }返回\’成功称为:\’ + param; } @Recover public String recunity(serviceException e,string param){logger.warn(\’重试失败,执行恢复方法,参数: {}\’,param);返回\’降级响应:\’ + param;在上面的示例中:
@Retryable annotation defines methods that need to be retry, including the type of exception that triggers retry, the maximum number of retrys and the backoff policy backoff property sets the initial delay of 1 second, and each delay time doubles (exponential backoff) @Recover annotation defines the recovery method after retry failure
注解方式
@Servicepublic class RemoteServiceClient { private final retrytemplate retrytemplate; @Autowired public EnferoteserviceClient(retrytemplate retrytemplate){this.retrytemplate=retrytemplate; } public String callWithRetry(String param) { return retryTemplate.execute(context – { //Retry business logic if (Math.random() 0.7) { throw new ServiceException(\’Service is temporarily unavailable\’); } return \’Called successfully : \’ + param; }, context – { //Recovery logic after retry failed return \’Downgrade response : \’ + param; }); } @bean public retrytemplate retrytemplate(){retrytemplate template=new retryTemplate(); //设置重试策略simpleereTryPolicy策略=新的SimpleerEtryPolicy();策略。 //设置策略endentialbackoffpolicy vackoffpolicy=new ExponentialBackoffPolicy(); backoffpolicy.setinitialinterval(1000); backoffpolicy.setmultiplier(2.0); template.setRypolicy(策略); template.setBackOffPolicy(向后poLicy);返回模板; }}
编程方式
优势
与春季生态系统的完美集成提供了丰富的重试策略和配置选项,以支持两种注释和编程方式。灵活的使用可以准确控制重试异常类型的缺点。
依靠弹簧框架代码相对侵入性。在复杂的情况下,配置略有复杂。与其他容错机制集成需要额外的工作。
4. 优缺点
春季生态系统中的项目需要精心控制重试条件和策略。结合重试条件和策略的场景。需要业务方案方法级重试要求。
5. 适用场景
二、Resilience4j Retry
rsilience4j是一个受Netflix Hystrix启发的轻质容错库。弹性4J重试模块提供强大的重试功能。与Spring Retry不同,Resilience4J采用功能性编程样式,并使用Decorator模式实现重试功能。
弹性的功能4J重试:
基于功能界面,没有外部依赖性,轻质设计可以与其他容忍故障机制(例如断路器,电流限制器)无缝集成,以提供丰富的监视指标010-10 3:010将Resilience 4J在Springboot项目中集成:
依赖项groupIdio.github.risilience4j/groupId artifactidResilience4j-spring-boot2/artifactid version1.7.0/version/distry/distionencyDependencyDependency groupId.springframework.boot/groupId/groupIdsId artifactidsidspring-boot boot-boot-boot-starter-starter-starter-starter-aop-aop/artifactid/distrifactid/disterencyconfig application.yml:
resilience4j.retry: instances: backendService: maxAttempts: 3 waitDuration: 1s enableExponentialBackoff: true exponentialBackoffMultiplier: 2 retryExceptions: – java.io.IOException – java.util.concurrent.TimeoutException
1. 基本原理
弹性4J还支持注释方法和编程方法。
2. 集成配置
@ServicePublic类BackendService {private static final logger logger=loggerfactory.getLogger(backendservice.class); @retry(name=\’BackendService\’,hallbackMethod=\’shortbackCall\’)public String callbackendService(string param){logger.info(\’call backend service,parameter : {}\’,param); if(Math.random()0.7){Logger.error(\’服务呼叫失败\’);投掷新的IOException(“服务连接失败”); }返回\’后端服务响应:\’ + param; } public String hallbackCall(String param,exception ex){logger.warn(\’所有重试失败,执行降级方法,参数: {}\’,param);返回\’降级响应:\’ + param; }}
3. 使用方法
@ServicePublic类BackendService {私有最终重试重新指定;私有最终记录器logger=loggerfactory.getLogger(backendservice.class); @Autowired public BackendService(重试retryRegistry){this.retryRegistry=retryRegistry; } public String executeWithRetry(String param){//获取配置的重试验retry retry retry=retryRegistry.retry(\’BackendService\’); //创建一个可重试函数checkedfunction0string retryableFunction=retry.decoratecheckedSupplier(retry,() – callbackendService(param));尝试{//执行重试返回retryableFunction.apply(); } catch(可投掷){logger.error(\’retry失败: {}\’,throwable.getMessage());返回\’降级响应:\’ + param; }} private string callbackendService(string param)抛出ioexception {logger.info(\’调用后端服务,参数: {}\’,param);如果(Math.random()0.7){抛出新的ioexception(\’服务连接失败\’); }返回\’后端服务响应:\’ + param; }}
注解方式
优势
轻巧的设计,功能性编程样式,没有外部依赖性,简单的代码,丰富的监视和统计指标,它们可以与易于故障的机制(例如断路器和当前限制器)无缝集成,支持各种高级重试策略。缺点
学习曲线相对陡峭,尤其是功能主义的概念。对于不熟悉功能编程的开发人员,一些高级功能需要其他配置。
编程方式
一个系统,需要对微服务体系结构中的指标进行详细监控,该系统需要与其他容忍性的机制结合使用。
4. 优缺点
5. 适用场景
Guava重试是Google Guava库提供的重试机制。它提供了一个简单且灵活的API来实现重试功能。
Guava重试通过建造器模式提供灵活的重试配置,该模式可以自定义重试条件,停止策略,等待策略等。
三、Guava Retrying
集成在Springboot项目中重试番石榴:
依赖项groupIdcom.github.rholder/groupId artifactidguava-retrying/artifactid version2.0.0/version/version/decterent
1. 基本原理
guava guava guava主要在编程中使用:
@ServicePublic类ExternalServiceClient {private static final logger logger=loggerfactory.getLogger(externalServiceClient.Class);公共字符串callexternalService(字符串param){retryerString retryer=retryerBuilder.StringNewBuilder().retryifexception()//如果发生任何例外,请retryifResult(结果- 结果====null)//如果结果为NULL.WILL.WITHWAITATERATEGY(exptstrate) timeunit.milliseconds))//指数向后。 trib.getAttEmptNumber(); if(trib.hasexception()){logger.error(\’exception: {}\’,from.getExceptioncause()。尝试{return retryer.call(() – {logger.info(\’调用外部服务,参数: {}\’,param); //模拟服务调用if(Math.random()0.7){thur new RuntimeException {thur new RuntimeException(\’Service(\’service\’Service(\’service\’service\’service\’service\’\’是暂时不可用的\’外部服务\’);}\’\’\’\’外部服务响应\’\’);}外部服务响应333333333:\’ + param;});}); } catch(retryException | executionException e){logger.error(\’retry失败: {}\’,e.getMessage());返回\’降级响应:\’ + param; }}}在Springboot中创建一个可重复使用的重试bean:
@configurationpublic类RetryConfig {@Bean public t retryert d retryert defaultretryer(){返回retryerBuilder.tNewBuilder().tnewbuilder().retryifexception()retryifryifResult(predicates.isnull() 。 }}@servicePublic class serviceWithRetry {私有最终重试屈曲; @Autowired public ServiceWithRetry(retryerString retryer){this.tryer=retryer; } public String executeWithRetry(字符串input)抛出executionException,retryException {return retryer.call(() – {//Business Logic return return processInput(input);}); }}
2. 集成配置
Guava重试提供了丰富的自定义选项:
retryerString复合物=retryerBuilder.StringNewBuilder()//自定义重试条件.retryifexceptionoftype(ioexception.class).retryifexception .retryifexception(e -e -e -e ackof timeOutEfexception).RERTRYIFRESULT(RESTRYIFRESULT(RESLER -RESTIR -RESTIRE -restion!=null RESTIRE.CONTIASS.CONTIASS) 。 timeunit.seconds)//自定义阻止策略.withBlockStrategy(blockstrategies.threadsleepstrategy()).build();
3. 使用方法
优势
API简单明了,易于使用。高度可定制的重试条件,等待政策和停止政策不依赖春季框架。它可以在任何Java项目中使用。
没有注释支持,只能在编程中使用与春季生态系统的深层集成。没有内置的监视和统计功能停止。更新的
4. 高级特性
简单重试需求方案,在该方案中,需要高度自定义重试的项目对于较少弹簧的项目需要高度自定义的逻辑。
5. 优缺点
6. 适用场景
FAILSAFE是一个相对较新的Java重试图书馆,重点是高性能和低延迟方案。它的设计目标是提供一种简单有效的重试机制,同时保持API的简单性和易用性。 FailSafe支持同步和异步重试,具有灵活的重试策略和最小的依赖性。
2
. 集成配置
在SpringBoot项目中集成failsafe
<dependency> <groupId>dev.failsafe</groupId> <artifactId>failsafe</artifactId> <version>3.3.2</version></dependency>failsafe通常通过dev.failsafe:failsafe库来使用,这是一个现代化的重试和容错库。
3. 使用方法
failsafe主要采用编程方式使用,具有流式API设计
@Servicepublic class FailsafeService { private static final Logger logger = LoggerFactory.getLogger(FailsafeService.class); public String executeWithRetry(String param) { return Failsafe.with( // 配置重试策略 RetryPolicy.<String>builder() .handle(IOException.class, TimeoutException.class) .withMaxRetries(3) .withDelay(Duration.ofSeconds(1)) .withMaxDuration(Duration.ofSeconds(10)) .withBackoff(Duration.ofMillis(100), Duration.ofSeconds(2)) .onRetry(event -> logger.info(\”第{}次重试,上次异常: {}\”, event.getAttemptCount(), event.getLastException().getMessage())) .onFailure(event -> logger.error(\”重试失败,尝试次数: {}, 总耗时: {}ms\”, event.getAttemptCount(), event.getElapsedTime().toMillis())) .build() ) .get(() -> { logger.info(\”执行操作,参数: {}\”, param); // 模拟操作 if (Math.random() > 0.7) { throw new IOException(\”操作暂时失败\”); } return \”操作成功: \” + param; }); } // 异步重试示例 public CompletableFuture<String> executeWithRetryAsync(String param) { return Failsafe.with( RetryPolicy.<String>builder() .handle(IOException.class) .withMaxRetries(3) .withBackoff(Duration.ofMillis(100), Duration.ofSeconds(1)) .build() ) .getAsync(() -> { logger.info(\”异步执行操作,参数: {}\”, param); // 模拟异步操作 if (Math.random() > 0.7) { throw new IOException(\”异步操作暂时失败\”); } return \”异步操作成功: \” + param; }); } // 带降级的重试示例 public String executeWithFallback(String param) { return Failsafe.with( RetryPolicy.<String>builder() .handle(IOException.class) .withMaxRetries(3) .build(), // 降级策略 Fallback.of(e -> \”降级响应: \” + param) ) .get(() -> { // 业务逻辑 if (Math.random() > 0.7) { throw new IOException(\”操作失败\”); } return \”操作成功: \” + param; }); }}在SpringBoot中创建可复用的RetryPolicy bean
@Configurationpublic class FailsafeConfig { @Bean public RetryPolicy<Object> defaultRetryPolicy() { return RetryPolicy.builder() .handle(Exception.class) .withMaxRetries(3) .withBackoff(Duration.ofMillis(100), Duration.ofSeconds(1), 2.0) .build(); } @Bean public Fallback<Object> defaultFallback() { return Fallback.of(e -> { if (e instanceof ServiceException) { return \”服务异常降级\”; } return \”通用降级响应\”; }); }}@Servicepublic class ServiceWithFailsafeRetry { private final RetryPolicy<Object> defaultRetryPolicy; private final Fallback<Object> defaultFallback; @Autowired public ServiceWithFailsafeRetry(RetryPolicy<Object> defaultRetryPolicy, Fallback<Object> defaultFallback) { this.defaultRetryPolicy = defaultRetryPolicy; this.defaultFallback = defaultFallback; } public String executeWithRetry(String input) { return Failsafe.with(defaultRetryPolicy, defaultFallback) .get(() -> { // 业务逻辑 return processInput(input); }); }}
4. 优缺点
优点
极高的性能,适合高频调用场景支持同步和异步重试轻量级,依赖少与CompletableFuture良好集成内置丰富的监听器机制缺点
没有注解支持,只能通过编程方式使用与Spring框架集成度不高近几年更新也不活跃
5. 适用场景
高性能、低延迟要求的应用需要异步重试能力的场景需要细粒度控制重试行为的场景
五、四种重试机制的对比
特性
Spring Retry
Resilience4j Retry
Guava Retrying
Failsafe
编程模型
AOP + 命令式
函数式
命令式
流式
注解支持
支持
支持
不支持
不支持
依赖
Spring
无外部依赖
Guava
最小依赖
性能开销
中等
低
中等
极低
异步支持
有限
良好
有限
优秀
监控集成
有限
丰富
无
基本
配置方式
注解/编程
配置文件/注解/编程
编程
编程
与其他容错机制集成
有限
原生支持
无
良好
学习曲线
中等
较陡
平缓
平缓
可定制性
高
高
高
高
适用场景
Spring项目
微服务/云原生应用
简单场景/非Spring项目
用户评论
﹎℡默默的爱
这篇文章讲解得真不错!一直想了解SpringBoot的重试机制,现在终于明白了。以前遇到错误就直接抛出异常,可真是笨拙,如果早点知道可以用这些方法处理,那得多省心啊!
有20位网友表示赞同!
*巴黎铁塔
看了这篇文章,感觉自己对Spring Boot再也不是一片空白了。每个重试机制都有各自的优缺点,真得要把它们好好记住,以后遇到问题的时候还能派上用场!
有7位网友表示赞同!
有一种中毒叫上瘾成咆哮i
学习SpringBoot一直是我的目标,但那些复杂的技术原理总是让我望而却步。幸好遇到了这篇文章,用简洁易懂的语言帮我理清思路,现在总算明白了重试机制的重要性,看来得好好实践一下了!
有13位网友表示赞同!
拥抱
我一直在项目中使用 @Retryable 注解来处理一些可能会发生失败的操作,没想到还有这么多种实现方案,这下可以多尝试一下看看哪个更适合我的场景了。
有8位网友表示赞同!
我的黑色迷你裙
说白了,SpringBoot的重试机制就是为了避免因为短暂网络中断或者应用错误导致的服务中断吧!我之前就遇到过这种情况,当时真是手足无措,如果早点知道这些机制,早点把它运用到项目中,能省好多麻烦啊!
有10位网友表示赞同!
矜暮
作者讲解的是非常详细的。每一个重试机制的实现都有代码示例和说明,这对我这种喜欢实践学习的人来说简直太棒了!以后遇到类似的问题,可以直接翻开参考一下。感谢你的分享!
有5位网友表示赞同!
軨倾词
感觉这篇文章写得蛮好的,把SpringBoot中的重试机制都梳理了一遍。只是有点可惜的是,没有详细介绍每个重试机制在实际应用中具体怎么使用,这个部分的讲解可以再多一些细节,这样会更实用。
有11位网友表示赞同!
执念,爱
之前一直以为SpringBoot只能靠 @Retryable 注解来实现重试功能,没想到还有其他三种方案!这篇文章让我开了眼界,以后遇到类似问题时可以选择不同的方法进行解决。感谢作者分享了这些宝贵的知识!
有10位网友表示赞同!
◆残留德花瓣
我感觉这篇博文有点过于理论化,缺少具体应用案例的讲解。对于新手来说,可能需要结合实际项目来深入理解这些重试机制的使用方式。希望作者能后续更新一些实践指南或者案例讲解。
有16位网友表示赞同!
烬陌袅
这篇文章虽然详细讲解了SpringBoot中的四种重试机制,但并没有针对不同场景进行推荐,不知道在什么样的情况下应该选择哪一种方案呢?需要作者补充一下关于场景选择的建议和说明!
有12位网友表示赞同!
怪咖
SpringBoot的重试机制确实很常用,这篇博文讲解得挺清晰,把各个方案的特点都概括得很到位。我以前用的都是 @Retryable 注解,现在看来还有其他方法更好用,要好好学习一下!
有10位网友表示赞同!
孤岛晴空
终于找到一篇讲清楚SpringBoot重试机制的文章了!一直想弄懂这部分知识,现在总算是茅塞顿开!虽然有点复杂,但我决定好好把每个方案都研究透,以便在以后的开发中灵活运用。
有14位网友表示赞同!
发型不乱一切好办
这篇博文的内容很棒,但是我觉得文字描述还是有些抽象,如果能用一些图示或者流程图来辅助说明,更容易理解!
有10位网友表示赞同!
无所谓
我试着用 @FeignClient 来实现重试功能的时候遇到了一些问题,这篇文章里虽然有相关讲解,但我感觉内容略显不够详细。希望作者能够补充更多关于 @FeignClient 重试实践的例子和经验分享!
有12位网友表示赞同!
┲﹊怅惘。
这个主题确实很实用,SpringBoot中的重试机制有很多种方案,这篇文章做得比较全面。 我个人更倾向于采用自定义实现的方式,这样可以更加灵活地控制重试策略。
有18位网友表示赞同!
可儿
文章讲得很好,特别是对不同重试机制优缺点的对比分析非常有助于理解。如果能再提供一些实际应用场景的案例,那就更好啦!
有11位网友表示赞同!