Spring-Retry

news/2025/2/15 15:46:46/

Spring-Retry

引入Maven依赖

 <dependency><groupId>org.springframework.retry</groupId><artifactId>spring-retry</artifactId></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId></dependency>

使用@EnableRetry注解开启重试机制

@SpringBootApplication
@EnableRetry
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class,args);}
}

@Retryable说明

  • recover:用于重试失败的兜底策略,一般不使用这个属性
  • interceptor:忽略
  • value:支持重试的异常,与include等价,如果value和include都不配置则重试所有
  • include:需要重试的异常
  • exclude:不重试的异常
  • label:重试处的唯一名词定义,不定义则会基于方法签名生成,一般用不到
  • stateful:是否有状态的重试(需要学习spring-retry 有状态重试相关,一般用不到)
  • maxAttempts:最大执行次数
  • maxAttemptsExpression:忽略
  • backoff:重试策略
  • listeners:spring-retry监听器配置,此处配置的是监听器在ioc容器中的id,需要了解spring retry的监听器才会使用

Backoff说明

  • value:与delay效果等价,失败后等待多少ms重试下一次
  • delay:与value效果等价,失败后等待多少ms重试下一次
  • maxDelay:重试等待的最大时间,如果maxDelay<delay,则maxDelay默认为30000ms
  • multiplier:重试时间间隔指数增长倍数
  • delayExpression:延时表达式
  • maxDelayExpression:最大延时表达式
  • multiplierExpression:增长表达式
  • random:附加随机事件,需要multiplier>0

@Recover

一个方法如果需要recover策略,只需要在同类中加入一个方法,方法使用recover标记即可

注意:方法的第一个参数为异常类型,后面为原方法的参数

@Recover
public void defaultFallback(Exception e){//do it
}

测试

注解:@Retryable

效果:默认重试3次,下次重试延时1s

2023-04-13 10:34:36.277  INFO 16704 --- [           main] c.v.service.impl.HttpRestServiceImpl     : do request 2...
2023-04-13 10:34:37.289  INFO 16704 --- [           main] c.v.service.impl.HttpRestServiceImpl     : do request 2...
2023-04-13 10:34:38.296  INFO 16704 --- [           main] c.v.service.impl.HttpRestServiceImpl     : do request 2...

注解:@Retryable(maxAttempts = 7,include = {Exception.class},backoff = @Backoff(delay = 1000,maxDelay = 10000))

效果:重试7次,延时在1000ms-10000ms之间

2023-04-13 10:36:38.484  INFO 6024 --- [           main] c.v.service.impl.HttpRestServiceImpl     : do request3 ...
2023-04-13 10:36:41.342  INFO 6024 --- [           main] c.v.service.impl.HttpRestServiceImpl     : do request3 ...
2023-04-13 10:36:44.318  INFO 6024 --- [           main] c.v.service.impl.HttpRestServiceImpl     : do request3 ...
2023-04-13 10:36:48.794  INFO 6024 --- [           main] c.v.service.impl.HttpRestServiceImpl     : do request3 ...
2023-04-13 10:36:50.264  INFO 6024 --- [           main] c.v.service.impl.HttpRestServiceImpl     : do request3 ...
2023-04-13 10:36:59.808  INFO 6024 --- [           main] c.v.service.impl.HttpRestServiceImpl     : do request3 ...
2023-04-13 10:37:01.882  INFO 6024 --- [           main] c.v.service.impl.HttpRestServiceImpl     : do request3 ...

注解:@Retryable(maxAttempts = 5,include = {Exception.class},backoff = @Backoff(delay = 1000,multiplier = 2))

效果:重试5次,第一次延时为1000ms,之后为第一次的2倍

2023-04-13 10:39:11.654  INFO 5692 --- [           main] c.v.service.impl.HttpRestServiceImpl     : do request4 ...
2023-04-13 10:39:12.665  INFO 5692 --- [           main] c.v.service.impl.HttpRestServiceImpl     : do request4 ...
2023-04-13 10:39:14.667  INFO 5692 --- [           main] c.v.service.impl.HttpRestServiceImpl     : do request4 ...
2023-04-13 10:39:18.672  INFO 5692 --- [           main] c.v.service.impl.HttpRestServiceImpl     : do request4 ...
2023-04-13 10:39:26.673  INFO 5692 --- [           main] c.v.service.impl.HttpRestServiceImpl     : do request4 ...

注解:@Retryable(maxAttempts = 5,backoff = @Backoff(value = 1500,maxDelay = 10000,multiplier = 3))

效果:最大重试5次,第一次延时1500ms,之后为前一次延时时长3倍,时长大于10000ms时,则按10000ms计算

2023-04-13 10:41:43.491  INFO 13928 --- [           main] c.v.service.impl.HttpRestServiceImpl     : do request5 ...
2023-04-13 10:41:45.005  INFO 13928 --- [           main] c.v.service.impl.HttpRestServiceImpl     : do request5 ...
2023-04-13 10:41:49.510  INFO 13928 --- [           main] c.v.service.impl.HttpRestServiceImpl     : do request5 ...
2023-04-13 10:41:59.523  INFO 13928 --- [           main] c.v.service.impl.HttpRestServiceImpl     : do request5 ...
2023-04-13 10:42:09.525  INFO 13928 --- [           main] c.v.service.impl.HttpRestServiceImpl     : do request5 ...

失效场景

因为spring-retry采用的时aspectj动态代理,所以也会出现一些类似于spring事务的失效场景

例如

  • 在同一service中a方法调用b方法,b方法上标有@Retryable注解,那么在运行期间a方法调用b方法时相当于this.b(),而此时的this指向的是原本被代理的对象,所以会导致注解失效
  • 在service中主动try-catch方法中的异常,导致aop没有拦截到异常信息,所以也不会进行重试

http://www.ppmy.cn/news/42713.html

相关文章

技术+商业“双轮”驱动,量旋科技加速推进全方位的量子计算解决方案

【中国&#xff0c;深圳】4月14日&#xff0c;在第三个“世界量子日”&#xff0c;以“‘双轮’驱动 加速未来”为主题的量旋科技2023战略发布会在线上举办。 本次发布会&#xff0c;量旋科技全线升级了三大业务线产品&#xff1a;其中重点布局的超导量子计算体系产品&#xf…

优先级队列

目录 前言&#xff1a; 1、PriorityQueue的特性 .2 PriorityQueue常用接口介绍 Ⅰ、PriorityQueue常见的构造方法 Ⅱ、常用的方法 Ⅲ、PriorityQueue的扩容方式&#xff1a; 3、应用 前言&#xff1a; 普通的队列是一种先进先出的数据结构&#xff0c;元素在队列尾追加&…

Ajax简介、axios异步提交

一、Ajax简介 Ajax全称为&#xff1a;“Asynchronous JavaScript and XML”&#xff08;异步JavaScript 和 XML&#xff09; 使用ajax&#xff0c;可以无刷新状态更新页面&#xff0c;并且实现异步提交&#xff0c;提升了用户体验。Ajax其实质是利用浏览器提供的一个特殊的对象…

redis中的持久化操作AOF与RDB区别

通过阅读Redis官网&#xff1a; 持久性&#xff1a;是指将数据写入持久存储&#xff0c;例如固态磁盘 &#xff08;SSD&#xff09; 包括&#xff1a; RDB&#xff08;Redis数据库&#xff09;&#xff1a;RDB持久性按指定的时间间隔执行数据集的时间点快照AOF &#xff08;…

掌握这些“学习方法和工具”,让你事半功倍!

在中国这个高竞争的社会环境下&#xff0c;学习成为了每个人都需要掌握的技能。然而&#xff0c;学习并不仅仅是读书和听课&#xff0c;更是需要一系列高效的方法和习惯来提高效率。本文将介绍一些实用的学习经验和方法&#xff0c;以及推荐一些国内好的学习工具和平台&#xf…

Apollo配置中心使用篇

Apollo配置中心使用篇常见配置中心对比Apollo核心概念Apollo核心特性Apollo架构设计各模块介绍服务端设计客户端设计Apollo与Spring集成的底层原理Apollo安装安装apollo-portalconfig service和admin service部署多网卡问题解决修改Portal环境配置调整ApolloPortal配置Apollo权…

设备是如何实现延时关机的

文章目录1. 引言2. 延时关机的实现方式2.1 自建定时服务实现2.2 RocketMQ中间件实现2.2.1 生成端demo2.2.2 消费端demo3. 结尾1. 引言 在设备联动中&#xff0c;有些场景需要保持设备继续工作一段时间再关机。比如在厨房场景下&#xff0c;存在燃气灶和烟机的联动场景&#xf…

Docker开启并配置远程安全访问

前言 在工作学习中&#xff0c;为了提高项目部署效率&#xff0c;一般会在Idea中直接使用Docker插件连接服务器Docker容器&#xff0c;然后将项目打包与DockerFile一起build成Docker镜像部署运行。但是不可能服务器总是跟着主机的&#xff0c;因此呢时常会面临的一个问题就是从…