SpringBoot中如何优雅地使用重试
1 缘起
项目中使用了第三方的服务,
第三方服务偶尔会出现不稳定、连接不上的情况,
于是,在调用时为了保证服务的相对高可用,添加了超时连接重试,
当连接第三方服务超时时,多重试几次,比如3次,三次后仍连接不上,抛出异常,
在实际的测试过程中,重试一次即可连接到第三方服务,
提高了服务的可用性。
2 spring-retry
Spring提供了重试项目:spring-retry,用于处理项目中需要重试的方法,
spring-retry中提供了自定义参数,如重试次数、指定重试情况、重试延迟时间等,
满足不同的重试场景。
2.1 小插曲:试错过程
搜索SpringBoot如何使用重试注解时,发现需要使用spring-retry这个项目,在Maven仓库搜索了一下spring-retry,发现有多个版本,如下图,选择了最新版本2.0.4,启动项目时发现,无法运行。
环境:
Java8
SpringBoot2.4.5

<!-- https://mvnrepository.com/artifact/org.springframework.retry/spring-retry -->
<dependency><groupId>org.springframework.retry</groupId><artifactId>spring-retry</artifactId><version>2.0.4</version>
</dependency>
异常信息如下,版本不一致,进入spring-retry项目,查看项目配置。

java: 无法访问org.springframework.retry.annotation.Backoff
错误的类文件: /D:/install/maven/apache-maven-3.8.8/my-repository/org/springframework/retry/spring-retry/2.0.4/spring-retry-2.0.4.jar!/org/springframework/retry/annotation/Backoff.class
类文件具有错误的版本 61.0, 应为 52.0
请删除该文件或确保该文件位于正确的类路径子目录中。
查看spring-retry项目的配置文件,发现java版本为17,所以,使用java8无法启动项目,
因此,需要选择spring-retry对应Java8的版本。

2.2 正确过程
2.2.1 配置依赖
不指定spring-retry版本,Maven会自动下载合适的版本,本次自动下载的版本为1.3.1。
<!-- https://mvnrepository.com/artifact/org.springframework.retry/spring-retry -->
<dependency><groupId>org.springframework.retry</groupId><artifactId>spring-retry</artifactId>
</dependency>

2.2.2 重试注解@Retryable
为方法添加@Retryable注解,即可在方法遇到异常时,重试指定次数。

常用参数如下,如有其他开发需求,可继续查看源码中的其他参数。
| 序号 | 参数 | 描述 |
|---|---|---|
| 1 | value | 触发重试的异常情况 |
| 2 | maxAttempts | 最大重试次数,默认重试3次 |
| 3 | backoff | 补偿机制,delay重试延迟时间,单位:毫秒;multiplier延迟时间比例,延迟的具体时间为delay*multiplier(multiplier>0时生效,默认multiplier为0),当multiplier为0时,延迟时间即为delay |
2.2.3 添加启动注解@EnableRetry
启动类中添加开启重试注解:@EnableRetry
配置样例如下:

启动重试@EnableRetry后,Spring会全局启动重试注解@Retryable,在执行重试方法时,通过CGLIB代理方法,根据注解的元数据进行重试,EnableRetry源码如下:
org.springframework.retry.annotation.EnableRetry

2.2.4 测试重试

重试结果:
重试参数:5次,延迟:2秒,比例:2
重试间隔:
第二次:第一次~第二次:2秒
第三次:第二次~第三次:22=4秒
第四次:第三次~第四次:42=8秒
第五次:第四次~第五次:8*2=16秒

3 小结
(1)Spring提供重试项目:spring-retry,支持自定义参数,如重试次数、指定重试情况、重试延迟时间等,满足不同的重试场景;
(2)spring-retry生效有两处配置:启动配置@EnableRetry,重试配置:@Retryable;
(3)延迟时间:第n次~第n+1次 第n次delay*multiplier,上一次的dealy与比例的乘积;
(4)使用spring-retry时需要注意与Java版本的匹配,不同的Java版本使用不同的spring-retry版本,以及不同的重试参数。
相关文章:
SpringBoot中如何优雅地使用重试
1 缘起 项目中使用了第三方的服务, 第三方服务偶尔会出现不稳定、连接不上的情况, 于是,在调用时为了保证服务的相对高可用,添加了超时连接重试, 当连接第三方服务超时时,多重试几次,比如3次&a…...
数据库日志解析:深入了解MySQL中的各类日志
**> 🎏:你只管努力,剩下的交给时间 🏠 :小破站 数据库日志解析:深入了解MySQL中的各类日志 前言第一:错误日志❌1. 错误日志的作用2. 记录内容3. 故障排查的方法 第二:查询日志1.…...
操作系统题目分类总结 | 进程管理 内存管理 文件系统 设备管理
系列文章如下 学习过程中一定要有系统观念(知识框架,每一章开头都会有一个思维导图),知道目前自己在学习的是哪一板块的内容,和前面有什么样的联系 操作系统的很多知识点前后都是联系非常紧密的,去一点一…...
数据结构——单链表(Singly Linked List)
1.链表介绍 链表是一种物理储存上非连续、非顺序的存储结构。数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。 对于上图,每一个结点都是一个结…...
4面试题--数据库(补充)
隔离性问题 若不考虑隔离性则会出现以下问题 1. 脏读:指⼀个事务在处理数据的过程中,读取到另⼀个 未提交 事务的数据 2. 不可重复读:指对于数据库中的某个数据(同⼀个数据项),⼀个事务内的多次查询却…...
人力资源管理后台 === 左树右表
1.角色管理-编辑角色-进入行内编辑 获取数据之后针对每个数据定义标识-使用$set-代码位置(src/views/role/index.vue) // 针对每一行数据添加一个编辑标记this.list.forEach(item > {// item.isEdit false // 添加一个属性 初始值为false// 数据响应式的问题 数据变化 视图…...
WordPress无需插件禁用WP生成1536×1536和2048×2048尺寸图片
我们在使用WordPress上传图片媒体文件的时候,是不是看到媒体库中有15361536和20482048的图片文件,当然这么大的文件会占用我们的服务器空间,如何禁止掉呢? function remove_default_image_sizes( $sizes) {unset( $sizes[1536x15…...
Git 与 Maven:企业级版本管理与版本控制规范设计
一、背景 当今,许多开发人员熟悉 GitFlow 工作流程,但往往忽略了 GitFlow 如何与 Maven 版本控制结合,尤其是在管理 snapshot 和 release 版本时的最佳实践。本文旨在整合 GitFlow 工作流程与 Maven 版本管理,提出一个统一的企业…...
Springmvc原理解析
1. DispatcherServlet springmvc的核心控制器,负责截获所有的请求,当截获请求后委托给HandlerMapping进行请求映射的解析工作,目的是找到哪一个Controller的方法可以处理该请求,找到后再交由给HandlerAdaptor去负责调用并返回Mod…...
Retrofit怎么返回一个JSON字符串?
项目用已经使用了 Retrofit,定义了接口方法,返回了 JSON 转换后的实体对象,炒鸡方便。但是总有意料之外的时候,比如我不需要返回实体对象,我要返回纯纯的 JSON 字符串,怎么办呢? 先看源码 通过…...
【GCC】2:chatgpt:SendSideBandwidthEstimation
webrtc中SendSideBandwidthEstimation类的设计 The SendSideBandwidthEstimation class in WebRTC is a critical component in its video engine. It’s responsible for deciding the video traffic rate that can be sent without overloading the network and thus maintai…...
OpenGL 自学总结
前言: 本人是工作后才接触到的OpenGL,大学找工作的时候其实比较着急,就想着尽快有个着落。工作后才发现自己的兴趣点。同时也能感觉到自己当前的工作有一点温水煮青蛙的意思,很担心自己往后能力跟不上年龄的增长。因此想在工作之余…...
java集合,ArrayList、LinkedList和Vector,多线程场景下如何使用 ArrayList
文章目录 Java集合1.2 流程图关系1.3 底层实现1.4 集合与数组的区别1.4.1 元素类型1.4.2 元素个数 1.5 集合的好处1.6 List集合我们以ArrayList集合为例1.7 迭代器的常用方法1.8 ArrayList、LinkedList和Vector的区别1.8.1 说出ArrayList,Vector, LinkedList的存储性能和特性1.…...
【2023.11.26】Mybatis自定义映射规则学习
创建自定义映射规则 <select id"selectArtist" resultMap"test">select * from artist </select> 在SQL语句标签中将resultType修改为resultMap,即自定义映射的id。 编写自定义映射规则: <resultMap id"tes…...
Nginx(九) aio sendfile directio 组合使用测试(2)
测试7:开启directio2m、sendfile,关闭aio,请求/vendor.js {"time_iso8601":"2023-11-26T22:47:3508:00","request_uri":"/vendor.js","status":"200","bytes_sent":…...
使用ETLCloud实现CDC实时数据集成:从MySQL到ClickHouse的实时数据同步
背景 在上一篇文章中体验了 ETLCloud 的离线数据迁移功能,就像大数据领域里有离线计算和实时计算, ETLCloud 还提供了基于 CDC (Change Data Capture)的实时数据集成功能:实时数据集成是指通过变化数据捕获技术&#…...
【云平台】STM32微信小程序阿里云平台学习板
【云平台】STM32微信小程序阿里云平台学习板 文章目录 前言一、立创EDA(硬件设计)1.主控STM32F103C8T62.ESP8266模块3.温湿度模块4.光照强度模块5.OLED显示模块6.PCB正面7.PCB反面8.3D视角正面9.3D视角反面 二、【云平台】STM32微信小程序阿里云平台学习…...
【研究中2】sql server权限用户设置
--更新时间2023.11.26 21:30 负责人:jerrysuse DBAliCMSIF EXISTS (select * from sysobjects where namehkcms_admin)--判断是否存在此表DROP TABLE hkcms_adminCREATE TABLE hkcms_admin (id int identity(1, 1),--id int primary key identity…...
从零开始学习管道:管道程序的优化和文件描述符继承问题
📟作者主页:慢热的陕西人 🌴专栏链接:Linux 📣欢迎各位大佬👍点赞🔥关注🚓收藏,🍉留言 本博客主要内容管道后续的完善,以及解决管道继承多个文件描…...
【JavaWeb】HTMLCSSJavaScript
HTML&CSS&JavaScript 文章目录 HTML&CSS&JavaScript一、开发工具及在线帮助文档二、 HTML2.1 HTML&CSS&JavaScript的作用2.2 HTML基础结构2.3 HTML概念词汇解释2.4 HTML的语法规则2.5 常用标签 三、CSS3.1 引入方式3.2 CSS选择器3.3 CSS浮动3.4 CSS定位…...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...
华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
快刀集(1): 一刀斩断视频片头广告
一刀流:用一个简单脚本,秒杀视频片头广告,还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农,平时写代码之余看看电影、补补片,是再正常不过的事。 电影嘛,要沉浸,…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能
1. 开发环境准备 安装DevEco Studio 3.1: 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK 项目配置: // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...
Spring Security 认证流程——补充
一、认证流程概述 Spring Security 的认证流程基于 过滤器链(Filter Chain),核心组件包括 UsernamePasswordAuthenticationFilter、AuthenticationManager、UserDetailsService 等。整个流程可分为以下步骤: 用户提交登录请求拦…...
goreplay
1.github地址 https://github.com/buger/goreplay 2.简单介绍 GoReplay 是一个开源的网络监控工具,可以记录用户的实时流量并将其用于镜像、负载测试、监控和详细分析。 3.出现背景 随着应用程序的增长,测试它所需的工作量也会呈指数级增长。GoRepl…...
Qwen系列之Qwen3解读:最强开源模型的细节拆解
文章目录 1.1分钟快览2.模型架构2.1.Dense模型2.2.MoE模型 3.预训练阶段3.1.数据3.2.训练3.3.评估 4.后训练阶段S1: 长链思维冷启动S2: 推理强化学习S3: 思考模式融合S4: 通用强化学习 5.全家桶中的小模型训练评估评估数据集评估细节评估效果弱智评估和民间Arena 分析展望 如果…...
开疆智能Ethernet/IP转Modbus网关连接鸣志步进电机驱动器配置案例
在工业自动化控制系统中,常常会遇到不同品牌和通信协议的设备需要协同工作的情况。本案例中,客户现场采用了 罗克韦尔PLC,但需要控制的变频器仅支持 ModbusRTU 协议。为了实现PLC 对变频器的有效控制与监控,引入了开疆智能Etherne…...
前端打包工具简单介绍
前端打包工具简单介绍 一、Webpack 架构与插件机制 1. Webpack 架构核心组成 Entry(入口) 指定应用的起点文件,比如 src/index.js。 Module(模块) Webpack 把项目当作模块图,模块可以是 JS、CSS、图片等…...
