😄 19年之后由于某些原因断更了三年,23年重新扬帆起航,推出更多优质博文,希望大家多多支持~
🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志
🎐 个人CSND主页——Micro麦可乐的博客
🐥《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程,入门到实战
🌺《RabbitMQ》专栏主要介绍使用JAVA开发RabbitMQ的系列教程,从基础知识到项目实战
🌸《设计模式》专栏以实际的生活场景为案例进行讲解,让大家对设计模式有一个更清晰的理解
💕《Jenkins实战》专栏主要介绍Jenkins+Docker的实战教程,让你快速掌握项目CI/CD,是2024年最新的实战教程
🌞《Spring Boot》专栏主要介绍我们日常工作项目中经常应用到的功能以及技巧,代码样例完整
如果文章能够给大家带来一定的帮助!欢迎关注、评论互动~
Spring Boot集成 Spring Retry 实现容错重试机制
1、前言
本文对应源码下载地址: https://download.csdn.net/download/lhmyy521125/89430153 无需积分
在日常开发过程中,我们经常会与第三方接口进行交互,例如:
短信发送
、
远程服务调用
、
争抢锁
等场景,当正常调用发生异常时,例如:
网络延迟
、
服务宕机
或
临时故障
等问题,会导致本次请求交互失败,而借助
Spring Retry
能够帮助我们在方法调用失败时自动重试,从而提高系统的稳定性和健壮性。
本文跟着博主由浅入深一起来学习
Spring Retry
!
2、什么是 Spring Retry?
Spring Retry 是一个用于简化 Java 方法重试逻辑的库,它能够在方法调用失败时自动重试,并提供了丰富的配置选项,支持重试次数、重试间隔时间、异常类型等配置。通过使用 Spring Retry,可以方便地在 Spring Boot 应用中实现容错和重试机制。
Spring Retry 的特性
- 自动重试:当方法调用失败时,根据配置的重试策略自动重试
- 支持多种异常类型:可以配置在遇到特定异常时重试,如
IOException
、SQLException
等- 重试间隔控制:支持配置重试间隔时间,可以设置固定间隔或指数增长间隔
- 自定义重试策略:提供了灵活的重试策略接口,可以实现自定义的重试逻辑
3、开始简单集成
构建你的
Spring Boot
项目,在
pom.xml
中引入依赖
<dependency><groupId>org.springframework.retry</groupId><artifactId>spring-retry</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>
配置
Spring Retry
可以通过注解或配置文件进行配置。下面展示如何使用注解方式配置
使用@EnableRetry注解开启
在主类 或对应配置类上加@EnableRetry注解,表示启用重试机制
@SpringBootApplication@EnableRetrypublic class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
使用 @Retryable 注解
@Retryable
注解是
Spring Retry
的核心注解,用于标记需要重试的方法。示例代码如下:
importorg.springframework.retry.annotation.Backoff;importorg.springframework.retry.annotation.Retryable;importorg.springframework.stereotype.Service;@ServicepublicclassRetryService{//初始化重试次数privateint attempt =0;@Retryable(value ={RuntimeException.class}, maxAttempts =5, backoff =@Backoff(delay =2000))publicStringretryMethod(){
attempt++;System.out.println("重试次数Attempt: "+ attempt);if(attempt <3){thrownewRuntimeException("出现故障, 重试中...");}return"Success!";}}
配置参数说明
value
指定了需要重试的异常类型,这里是 RuntimeException
maxAttempts
设置了最大重试次数,这里是 5 次
backoff
设置了重试间隔,使用
@Backoff
注解指定延迟时间,单位是毫秒,这里是 2000 毫秒(2秒)
创建一个controller,用于调用重试方法,并测试重试逻辑:
import com.example.demo.service.RetryService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;@RestControllerpublic class RetryController {
@Autowired
private RetryService retryService;@GetMapping("/retry")public String retry() {
try {
return retryService.retryMethod();
} catch (Exception e) {
return"重试失败: "+ e.getMessage();
}
}
}
接口请求测试
观察控制台
测试你会发现接口请求过程中,控制台一直输出了三次重试次数后成功返回,你以为
Spring Retry
就这么点东西?我们继续往下看
4、Spring Retry的高级配置
❶ 自定义重试策略
在某些情况下,默认的重试策略可能无法满足需求,这时可以通过实现
RetryPolicy
接口来自定义重试策略,控制重试的逻辑和条件
importorg.springframework.retry.RetryContext;importorg.springframework.retry.RetryPolicy;publicclassCustomRetryPolicyimplementsRetryPolicy{privatestaticfinalintMAX_RETRIES=3;@OverridepublicbooleancanRetry(RetryContext context){// 检查重试次数int retryCount = context.getRetryCount();if(retryCount >=MAX_RETRIES){returnfalse;// 如果重试次数达到最大值,不再重试}// 检查异常类型Throwable lastException = context.getLastThrowable();if(lastException instanceofMyCustomException){// 如果是我们关心的特定异常类型,允许重试returntrue;}// 其他情况下不允许重试returnfalse;}//MyCustomException 是你定义的异常类型publicclassMyCustomExceptionextendsException{/* ... */}//在重试操作开始时创建新的上下文对象,用于存储重试信息@OverridepublicRetryContextopen(RetryContext retryContext){returnnull;}//在重试操作结束时执行清理或记录操作@Overridepublicvoidclose(RetryContext retryContext){}//在重试过程中遇到异常时记录异常信息@OverridepublicvoidregisterThrowable(RetryContext retryContext,Throwable throwable){}}
canRetry方法的介绍
booleancanRetry(RetryContext context);
canRetry
方法是重试策略的核心逻辑,通过检查当前的重试上下文信息,决定是否可以继续进行重试。通常会根据重试次数、异常类型等条件来判断是否继续重试
作用:判断是否应该继续进行重试操作
参数:RetryContext context,表示当前的重试上下文,包含了重试次数、上次异常等信息
返回值:boolean,返回 true 表示可以继续重试,返回 false 表示停止重试
open方法的介绍
RetryContextopen(RetryContext parent);
在重试操作开始时,
Spring Retry
会调用
open
方法创建一个新的
RetryContext
,这个上下文对象会在整个重试过程中传递,用于存储重试相关的信息
作用:创建并返回一个新的 RetryContext 对象,表示一次新的重试操作的上下文信息
参数:RetryContext parent,表示父级上下文,如果没有父级上下文则为 null
返回值:RetryContext,表示新的重试上下文
close方法的介绍
当重试操作完成后,无论是否成功,
Spring Retry
都会调用
close
方法,可以在这个方法中执行一些清理操作或记录日志
voidclose(RetryContext context);
作用:在重试操作完成时(无论成功或失败)调用,用于清理或记录重试操作的结束
参数:RetryContext context,表示当前的重试上下文
registerThrowable方法的介绍
voidregisterThrowable(RetryContext context,Throwable throwable);
在重试过程中,如果遇到异常,
Spring Retry
会调用
registerThrowable
方法,将异常信息记录到
RetryContext
中。这个信息可以在后续的重试操作中使用
作用:在重试过程中遇到异常时调用,用于记录当前的异常信息
参数:RetryContext context,表示当前的重试上下文
参数:Throwable throwable,表示当前遇到的异常
在
Spring
配置中使用自定义
RetryPolicy
,同时也可以配置定制
RetryTemplate
importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.retry.backoff.FixedBackOffPolicy;importorg.springframework.retry.support.RetryTemplate;@ConfigurationpublicclassRetryConfig{@BeanpublicRetryTemplateretryTemplate(){RetryTemplate retryTemplate =newRetryTemplate();// 设置自定义的RetryPolicyCustomRetryPolicy retryPolicy =newCustomRetryPolicy(5);// 还可以设置其他的策略,如BackoffPolicy等 FixedBackOffPolicy backOffPolicy =newFixedBackOffPolicy();
backOffPolicy.setBackOffPeriod(2000);
retryTemplate.setRetryPolicy(retryPolicy);
retryTemplate.setBackOffPolicy(backOffPolicy);return retryTemplate;}}
❷ 使用 RetryTemplate
RetryTemplate
是
Spring Retry
提供的一个模板类,允许我们更细粒度地控制重试逻辑。下面是使用 RetryTemplate 的例子
importorg.springframework.retry.support.RetryTemplate;importorg.springframework.stereotype.Service;@ServicepublicclassTemplateRetryService{privatefinalRetryTemplate retryTemplate;publicTemplateRetryService(RetryTemplate retryTemplate){this.retryTemplate = retryTemplate;}publicStringexecuteWithRetry(){return retryTemplate.execute(context ->{System.out.println("TemplateRetryService执行重试..");if(Math.random()<0.7){thrownewRuntimeException("重试失败");}return"Success!";});}}
5、代码汇总
Spring Retry
也是可以与
Spring AOP
配合使用,通过切面拦截方法调用,实现全局的重试逻辑,只需要创建一个切面即可
importorg.aspectj.lang.annotation.Aspect;importorg.aspectj.lang.annotation.Before;importorg.springframework.retry.annotation.Retryable;importorg.springframework.stereotype.Component;@Aspect@ComponentpublicclassRetryAspect{@Before("@annotation(org.springframework.retry.annotation.Retryable)")publicvoidbeforeRetry(){System.out.println("执行重试前...");//比如记录请求发起的时间等}}
讲解了这么多,我们还是把代码汇总一下,进行一次演示,编写一个
Controller
用来测试两个重试服务
@RestController@RequestMapping("/api")public class RetryController {
@Autowired
private RetryService retryService;@Autowired
private TemplateRetryService templateRetryService;@GetMapping("/retry")public String retry() {
try {
return retryService.retryMethod();
} catch (Exception e) {
return"重试失败: "+ e.getMessage();
}
}
@GetMapping("/template-retry")public String templateRetry() {
return templateRetryService.executeWithRetry();
}
}
最终代码结构如下:(目的只是为了演示忽略都在一个包中)
再次运行测试,分别测试
/api/retry
接口以及模板重试服务的接口
/api/template-retry
,结果如下:
OK,至此
Spring Retry
的介绍以及使用已经讲完了,小伙伴们可以根据代码片段自行定制自己的重试策略
6、总结
Spring Retry
是一个强大的工具,能够帮助我们在系统出现临时故障时自动重试,提高系统的稳定性和健壮性。在实际开发中,根据具体的业务需求和系统情况,合理配置和使用
Spring Retry
,可以显著提升系统的可靠性。
本文的代码主要是演示使用,小伙伴们可以根据自己业务需求进行修改升级。如果本文对您有所帮助,希望 一键三连 给博主一点点鼓励,如果您有任何疑问或建议,请随时留言讨论
版权归原作者 Micro麦可乐 所有, 如有侵权,请联系我们删除。