自己动手实践 spring retry 重试框架

简介: 前序马上过年了,预祝大家,新年快乐,少写bug什么是spring retry?spring retry是从spring batch独立出来的一个能功能,主要实现了重试和熔断。什么时候用?远程调用超时、网络突然中断可以重试。

前序

马上过年了,预祝大家,新年快乐,少写bug

什么是spring retry?

spring retry是从spring batch独立出来的一个能功能,主要实现了重试和熔断。

什么时候用?

远程调用超时、网络突然中断可以重试。对于重试是有场景限制的,不是什么场景都适合重试,比如参数校验不合法、写操作等(要考虑写是否幂等)都不适合重试。

怎么用?

1,首先我们新建一个maven工程(如果不会,请移步 http://www.cnblogs.com/JJJ1990/p/8384386.html,大佬请忽略),然后在pom文件中引入spring retry 的jar包,代码如下:

1   <!-- spring-retry重试机制  -->
2         <dependency>
3             <groupId>org.springframework.retry</groupId>
4             <artifactId>spring-retry</artifactId>
5             <version>1.1.2.RELEASE</version>
6         </dependency>

2,编写重试部分代码,我们直接在app类的main方法中实现

首先我们先制定好重试策略,也就是当异常发生后,我们重试几次,每次间隔多久等

如下代码中,第一行为新建一个重试模板,第二行为制定一个简单重试策略,特别注意最后的数字3,这就是我们设置的要重试的次数

1 final RetryTemplate retryTemplate = new RetryTemplate();
2         final SimpleRetryPolicy policy = new SimpleRetryPolicy(3, 
3                 Collections.<Class<? extends Throwable>,
4                 Boolean>singletonMap(Exception.class, true));

3,下面再设置退避策略,注意第二行 2000为每次间隔的时间,单位ms,然后再将 重试策略和退避策略设置到重试模板中如第3.4行

1 FixedBackOffPolicy fixedBackOffPolicy = new FixedBackOffPolicy();
2         fixedBackOffPolicy.setBackOffPeriod(2000);
3         retryTemplate.setRetryPolicy(policy);
4         retryTemplate.setBackOffPolicy(fixedBackOffPolicy);

4,编写重试业务部分代码如下,主要是实现RetryCallback接口的 doWithRetry 方法,在这个里面就是编写主要的业务逻辑了。我在这块模拟了一个异常,通过数组下标越界异常,来进行重试

1 final RetryCallback<String, Exception> retryCallback = new RetryCallback<String, Exception>() {
2             public String doWithRetry(RetryContext context) throws Exception {
3                 System.out.println(new Date());
4                 System.out.println("retryCallback");
5                 String [] str = new String [2];
6                 str[3] = "";
7                 return "1";
8             }
9         };

5,编写恢复回调代码如下,也是实现了RecoveryCallback接口中的recover方法,这个方法的作用就是当第4步重试代码按照重试策略执行完毕后,依旧异常,那就会执行下面的代码,这样你就可以通过下面的代码,来规避异常

1 final RecoveryCallback<String> recoveryCallback = new RecoveryCallback<String>() {
2             public String recover(RetryContext context) throws Exception {
3                 System.out.println("recoveryCallback");
4                 return null;
5             }
6         };

6,编写重试模板执行重试代码及恢复回调代码

1 try {
2             System.out.println("retryTemplate execute start");
3             String response = retryTemplate.execute(retryCallback, recoveryCallback);
4             System.out.println("retryTemplate execute end");
5         } catch (Exception e) {
6             e.printStackTrace();
7         }

测试代码

启动程序,注意整个代码是全部在main方法中实现的,我们直接启动程序看打印的日志信息,从日志信息中可以得知,我们在启动程序后先进入execute方法,然后执行retrycallback,但是每次执行的时候都有数组下标越觉异常,所以他就重试了3次,而且每次的时间间隔是我们设置的2秒,当第三次执行失败后,就调用recovercallback方法,然后整个程序结束。

退别策略有哪些?

1,我们上面的代码中用的退别策略是固定时间间隔,还有其他几种的退避策略大致如下:

  • NoBackOffPolicy:无退避算法策略,每次重试时立即重试

  • FixedBackOffPolicy:固定时间的退避策略,需设置参数sleeper和backOffPeriod,sleeper指定等待策略,默认是Thread.sleep,即线程休眠,backOffPeriod指定休眠时间,默认1秒

  • UniformRandomBackOffPolicy:随机时间退避策略,需设置sleeper、minBackOffPeriod和maxBackOffPeriod,该策略在[minBackOffPeriod,maxBackOffPeriod之间取一个随机休眠时间,minBackOffPeriod默认500毫秒,maxBackOffPeriod默认1500毫秒

  • ExponentialBackOffPolicy:指数退避策略,需设置参数sleeper、initialInterval、maxInterval和multiplier,initialInterval指定初始休眠时间,默认100毫秒,maxInterval指定最大休眠时间,默认30秒,multiplier指定乘数,即下一次休眠时间为当前休眠时间*multiplier

  • ExponentialRandomBackOffPolicy:随机指数退避策略,引入随机乘数可以实现随机乘数回退

我们将第3步的代码进行修改,如下:

1 ExponentialBackOffPolicy exponentialBackOffPolicy = new ExponentialBackOffPolicy();
2         exponentialBackOffPolicy.setInitialInterval(2000);
3         exponentialBackOffPolicy.setMultiplier(3);
4         exponentialBackOffPolicy.setMaxInterval(5000);
5         retryTemplate.setRetryPolicy(policy);
6         retryTemplate.setBackOffPolicy(exponentialBackOffPolicy);

上述代码中,2000为执行的时间间隔,3为倍数,5000为允许的最大间隔时间,执行代码结果如下:

如上图,第一次执行和第二次执行间隔2秒,第二次和第三次的间隔本来是2*3=6秒,但是由于设置了最大间隔所以在5秒的时候就触发了重试

重试业务中的异常不要捕获

在我们的重试业务代码中我们需要根据异常来进行重试,如果你在业务代码中捕获了异常会怎么样??我们修改下第4步代码看看:

 1 final RetryCallback<String, Exception> retryCallback = new RetryCallback<String, Exception>() {
 2             public String doWithRetry(RetryContext context) throws Exception {
 3                 System.out.println(new Date());
 4                 System.out.println("retryCallback");
 5                 try {
 6                     String [] str = new String [2];
 7                     str[3] = "";
 8                 } catch (Exception e) {
 9                     // TODO: handle exception
10                 }
11                 
12                 return "1";
13             }
14         };

如上,很简单,我们直接将数组异常try catch ,然后运行代码结果如下

如上图,从信息中可以看出,本来异常的代码只执行了一次,而且没有调用恢复回调代码。

所以如果你需要执行重试,那么就不要捕获你需要重试的异常信息。

所以如果你需要执行重试,那么就不要捕获你需要重试的异常信息。

所以如果你需要执行重试,那么就不要捕获你需要重试的异常信息。

重要的话说三遍~~~

 

 

 

  

 

自己动手搭建一个简易的SpringBoot环境

give me the ball!
相关文章
|
9天前
|
安全 Java Ruby
我尝试了所有后端框架 — — 这就是为什么只有 Spring Boot 幸存下来
作者回顾后端开发历程,指出多数框架在生产环境中难堪重负。相比之下,Spring Boot凭借内置安全、稳定扩展、完善生态和企业级支持,成为构建高可用系统的首选,真正经受住了时间与规模的考验。
79 2
消息中间件 Java Kafka
50 0
|
26天前
|
Java 测试技术 数据库
使用Spring的@Retryable注解进行自动重试
在现代软件开发中,容错性和弹性至关重要。Spring框架提供的`@Retryable`注解为处理瞬时故障提供了一种声明式、可配置的重试机制,使开发者能够以简洁的方式增强应用的自我恢复能力。本文深入解析了`@Retryable`的使用方法及其参数配置,并结合`@Recover`实现失败回退策略,帮助构建更健壮、可靠的应用程序。
106 1
使用Spring的@Retryable注解进行自动重试
|
3月前
|
安全 Java 微服务
Java 最新技术和框架实操:涵盖 JDK 21 新特性与 Spring Security 6.x 安全框架搭建
本文系统整理了Java最新技术与主流框架实操内容,涵盖Java 17+新特性(如模式匹配、文本块、记录类)、Spring Boot 3微服务开发、响应式编程(WebFlux)、容器化部署(Docker+K8s)、测试与CI/CD实践,附完整代码示例和学习资源推荐,助你构建现代Java全栈开发能力。
387 0
|
3月前
|
缓存 安全 Java
Spring 框架核心原理与实践解析
本文详解 Spring 框架核心知识,包括 IOC(容器管理对象)与 DI(容器注入依赖),以及通过注解(如 @Service、@Autowired)声明 Bean 和注入依赖的方式。阐述了 Bean 的线程安全(默认单例可能有安全问题,需业务避免共享状态或设为 prototype)、作用域(@Scope 注解,常用 singleton、prototype 等)及完整生命周期(实例化、依赖注入、初始化、销毁等步骤)。 解析了循环依赖的解决机制(三级缓存)、AOP 的概念(公共逻辑抽为切面)、底层动态代理(JDK 与 Cglib 的区别)及项目应用(如日志记录)。介绍了事务的实现(基于 AOP
121 0
|
3月前
|
存储 缓存 NoSQL
Spring Cache缓存框架
Spring Cache是Spring体系下的标准化缓存框架,支持多种缓存(如Redis、EhCache、Caffeine),可独立或组合使用。其优势包括平滑迁移、注解与编程两种使用方式,以及高度解耦和灵活管理。通过动态代理实现缓存操作,适用于不同业务场景。
319 0
|
3月前
|
缓存 JSON 前端开发
第07课:Spring Boot集成Thymeleaf模板引擎
第07课:Spring Boot集成Thymeleaf模板引擎
404 0
第07课:Spring Boot集成Thymeleaf模板引擎
|
3月前
|
Java Spring 容器
SpringBoot自动配置的原理是什么?
Spring Boot自动配置核心在于@EnableAutoConfiguration注解,它通过@Import导入配置选择器,加载META-INF/spring.factories中定义的自动配置类。这些类根据@Conditional系列注解判断是否生效。但Spring Boot 3.0后已弃用spring.factories,改用新格式的.imports文件进行配置。
750 0
|
4月前
|
Prometheus 监控 Cloud Native
Spring Boot 可视化监控
本文介绍了如何通过Spring Actuator、Micrometer、Prometheus和Grafana为Spring Boot应用程序添加监控功能。首先创建了一个Spring Boot应用,并配置了Spring Actuator以暴露健康状态和指标接口。接着,利用Micrometer收集应用性能数据,并通过Prometheus抓取这些数据进行存储。最后,使用Grafana将Prometheus中的数据可视化,展示在精美的仪表板上。整个过程简单易行,为Spring Boot应用提供了基本的监控能力,同时也为后续扩展更详细的监控指标奠定了基础。
689 2