Spring Boot集成 Spring Retry 实现容错重试机制并附源码
😄 19年之后由于某些原因断更了三年,23年重新扬帆起航,推出更多优质博文,希望大家多多支持~
🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志
🎐 个人CSND主页——Micro麦可乐的博客
🐥《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程,入门到实战
🌺《RabbitMQ》专栏主要介绍使用JAVA开发RabbitMQ的系列教程,从基础知识到项目实战
🌸《设计模式》专栏以实际的生活场景为案例进行讲解,让大家对设计模式有一个更清晰的理解
💕《Jenkins实战》专栏主要介绍Jenkins+Docker的实战教程,让你快速掌握项目CI/CD,是2024年最新的实战教程
🌞《Spring Boot》专栏主要介绍我们日常工作项目中经常应用到的功能以及技巧,代码样例完整
如果文章能够给大家带来一定的帮助!欢迎关注、评论互动~
Spring Boot集成 Spring Retry 实现容错重试机制
- 1、前言
- 2、什么是 Spring Retry?
- 3、开始简单集成
- 4、Spring Retry的高级配置
- ❶ 自定义重试策略
- canRetry方法的介绍
- open方法的介绍
- close方法的介绍
- registerThrowable方法的介绍
- ❷ 使用 RetryTemplate
- 5、代码汇总
- 6、总结
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
@EnableRetry
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}
使用 @Retryable 注解
@Retryable
注解是 Spring Retry
的核心注解,用于标记需要重试的方法。示例代码如下:
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;@Service
public class RetryService {//初始化重试次数private int attempt = 0;@Retryable(value = {RuntimeException.class}, maxAttempts = 5, backoff = @Backoff(delay = 2000))public String retryMethod() {attempt++;System.out.println("重试次数Attempt: " + attempt);if (attempt < 3) {throw new RuntimeException("出现故障, 重试中...");}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 {@Autowiredprivate RetryService retryService;@GetMapping("/retry")public String retry() {try {return retryService.retryMethod();} catch (Exception e) {return "重试失败: " + e.getMessage();}}
}
接口请求测试
观察控制台
测试你会发现接口请求过程中,控制台一直输出了三次重试次数后成功返回,你以为Spring Retry
就这么点东西?我们继续往下看
4、Spring Retry的高级配置
❶ 自定义重试策略
在某些情况下,默认的重试策略可能无法满足需求,这时可以通过实现 RetryPolicy
接口来自定义重试策略,控制重试的逻辑和条件
import org.springframework.retry.RetryContext;
import org.springframework.retry.RetryPolicy;public class CustomRetryPolicy implements RetryPolicy {private static final int MAX_RETRIES = 3;@Overridepublic boolean canRetry(RetryContext context) {// 检查重试次数int retryCount = context.getRetryCount();if (retryCount >= MAX_RETRIES) {return false; // 如果重试次数达到最大值,不再重试}// 检查异常类型Throwable lastException = context.getLastThrowable();if (lastException instanceof MyCustomException) {// 如果是我们关心的特定异常类型,允许重试return true;}// 其他情况下不允许重试return false;}//MyCustomException 是你定义的异常类型public class MyCustomException extends Exception { /* ... */ }//在重试操作开始时创建新的上下文对象,用于存储重试信息@Overridepublic RetryContext open(RetryContext retryContext) {return null;}//在重试操作结束时执行清理或记录操作@Overridepublic void close(RetryContext retryContext) {}//在重试过程中遇到异常时记录异常信息@Overridepublic void registerThrowable(RetryContext retryContext, Throwable throwable) {}
}
canRetry方法的介绍
boolean canRetry(RetryContext context);
canRetry
方法是重试策略的核心逻辑,通过检查当前的重试上下文信息,决定是否可以继续进行重试。通常会根据重试次数、异常类型等条件来判断是否继续重试
作用:判断是否应该继续进行重试操作
参数:RetryContext context,表示当前的重试上下文,包含了重试次数、上次异常等信息
返回值:boolean,返回 true 表示可以继续重试,返回 false 表示停止重试
open方法的介绍
RetryContext open(RetryContext parent);
在重试操作开始时,Spring Retry
会调用 open
方法创建一个新的 RetryContext
,这个上下文对象会在整个重试过程中传递,用于存储重试相关的信息
作用:创建并返回一个新的 RetryContext 对象,表示一次新的重试操作的上下文信息
参数:RetryContext parent,表示父级上下文,如果没有父级上下文则为 null
返回值:RetryContext,表示新的重试上下文
close方法的介绍
当重试操作完成后,无论是否成功,Spring Retry
都会调用 close
方法,可以在这个方法中执行一些清理操作或记录日志
void close(RetryContext context);
作用:在重试操作完成时(无论成功或失败)调用,用于清理或记录重试操作的结束
参数:RetryContext context,表示当前的重试上下文
registerThrowable方法的介绍
void registerThrowable(RetryContext context, Throwable throwable);
在重试过程中,如果遇到异常,Spring Retry
会调用 registerThrowable
方法,将异常信息记录到 RetryContext
中。这个信息可以在后续的重试操作中使用
作用:在重试过程中遇到异常时调用,用于记录当前的异常信息
参数:RetryContext context,表示当前的重试上下文
参数:Throwable throwable,表示当前遇到的异常
在Spring
配置中使用自定义 RetryPolicy
,同时也可以配置定制 RetryTemplate
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.retry.backoff.FixedBackOffPolicy;
import org.springframework.retry.support.RetryTemplate;@Configuration
public class RetryConfig {@Beanpublic RetryTemplate retryTemplate() {RetryTemplate retryTemplate = new RetryTemplate();// 设置自定义的RetryPolicyCustomRetryPolicy retryPolicy = new CustomRetryPolicy(5);// 还可以设置其他的策略,如BackoffPolicy等 FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();backOffPolicy.setBackOffPeriod(2000);retryTemplate.setRetryPolicy(retryPolicy);retryTemplate.setBackOffPolicy(backOffPolicy);return retryTemplate;}
}
❷ 使用 RetryTemplate
RetryTemplate
是 Spring Retry
提供的一个模板类,允许我们更细粒度地控制重试逻辑。下面是使用 RetryTemplate 的例子
import org.springframework.retry.support.RetryTemplate;
import org.springframework.stereotype.Service;@Service
public class TemplateRetryService {private final RetryTemplate retryTemplate;public TemplateRetryService(RetryTemplate retryTemplate) {this.retryTemplate = retryTemplate;}public String executeWithRetry() {return retryTemplate.execute(context -> {System.out.println("TemplateRetryService执行重试..");if (Math.random() < 0.7) {throw new RuntimeException("重试失败");}return "Success!";});}
}
5、代码汇总
Spring Retry
也是可以与 Spring AOP
配合使用,通过切面拦截方法调用,实现全局的重试逻辑,只需要创建一个切面即可
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Component;@Aspect
@Component
public class RetryAspect {@Before("@annotation(org.springframework.retry.annotation.Retryable)")public void beforeRetry() {System.out.println("执行重试前...");//比如记录请求发起的时间等}
}
讲解了这么多,我们还是把代码汇总一下,进行一次演示,编写一个Controller
用来测试两个重试服务
@RestController
@RequestMapping("/api")
public class RetryController {@Autowiredprivate RetryService retryService;@Autowiredprivate 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
,可以显著提升系统的可靠性。
本文的代码主要是演示使用,小伙伴们可以根据自己业务需求进行修改升级。如果本文对您有所帮助,希望 一键三连 给博主一点点鼓励,如果您有任何疑问或建议,请随时留言讨论
相关文章:

Spring Boot集成 Spring Retry 实现容错重试机制并附源码
😄 19年之后由于某些原因断更了三年,23年重新扬帆起航,推出更多优质博文,希望大家多多支持~ 🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志 🎐 个人CSND主页——Mi…...

MDK-ARM 编译后 MAP 文件分析
本文配合 STM32 堆栈空间分布 食用更佳! 一图胜千言。。。...
antv g6实现系统拓扑图
1 背景 为例描述各个服务、redis、mysql等之间的联系及其健康状态,构建系统拓扑图,考虑 g6 更适合处理大量数据之间的关系,所以我们采用g6来绘制前端的图形。 g6提供的支持: 节点/边类型多样,同样支持自定义对于节点…...
因路径规划异常导致导航停止 Failed to pass global plan to the controller
因路径规划异常导致导航停止 Failed to pass global plan to the controller 控制台错误信息: [ WARN] [1718875656.343893537, 93.698000000]: Transformed plan is empty. Aborting local planner! [ERROR] [1718875656.343922719, 93.698000000]: move_base.cpp:854 Faile…...
AOSP开发环境搭建
目录 一、安装虚拟机 二、安装Ubuntu 三、安装VMware tools 3.1、通用安装 3.2、Ubuntu22.04 中Drag and drop is not supported问题 四、安装依赖环境 4.1、安装git 4.2、下载Python3 4.3、解压Python3 4.4、编译与安装Python3 3.sudo make install 4.5、安装Pyth…...
React native新架构组成
React Native 的新架构(New Architecture)引入了一些新的组件和概念,旨在提高性能、增强灵活性和简化跨平台开发。主要组成部分包括: Fabric: Fabric Renderer: Fabric 是新的渲染引擎,它旨在取代现有的渲染引擎。与…...

Spring Security+Spring Boot实现登录认证以及权限认证
基本概念 “Authentication(认证)”是spring security框架中最重要的功能之一,所谓认证,就是对当前访问系统的用户给予一个合法的身份标识,用户只有通过认证才可以进入系统,在物理世界里,有点类似于“拿工卡刷门禁”的…...

5款堪称变态的AI神器,焊死在电脑上永不删除!
一 、AI视频合成工具——Runway: 第一款RunWay,你只需要轻轻一抹,视频中的元素就会被擦除,再来轻轻一抹,直接擦除,不喜欢这个人直接擦除,一点痕迹都看不出来。 除了视频擦除功能外,…...

Python和OpenCV图像分块之图像边长缩小比率是2
import cv2 import numpy as npimg cv2.imread("F:\\mytupian\\xihuduanqiao.jpg") # 低反光 cv2.imshow(image, img) # # 图像分块 # dst np.zeros(img.shape, img.dtype) ratio 2 #图像边长缩小比率是2,也就是一张图片被分割成四份 height, wi…...
C语言中的位域(bit-field)是什么,以及它的用途和优缺点
在C语言中,位域(bit-field)是一种特殊的数据结构,它允许在结构体(struct)中定义其成员所占用的位数,而不是使用整个字节或更大的内存空间。位域通常用于存储布尔值、状态标志、硬件控制位等&…...
从面试角度了解前端基础知识体系
目录 前端专业知识相关面试考察点 HTML 与 CSS Javascript 网络相关 浏览器相关 安全相关 算法与数据结构 计算机通用知识 前端项目经验相关面试考察点 前端框架与工具库 Node.js 与服务端 性能优化 前端工程化 开发效率提升 监控、灰度与发布 多人协作 结束语…...

【DKN: Deep Knowledge-Aware Network for News Recommendation】
DKN: Deep Knowledge-Aware Network for News Recommendation 摘要 在线新闻推荐系统旨在解决新闻信息爆炸的问题,为用户进行个性化推荐。 总体而言,新闻语言高度凝练,充满知识实体和常识。 然而,现有的方法并没有意识到这些外部…...

Linux管道与重定向
管道 是进程通信的方法之一,在Linux中用命令1|命令2的形式表示,将前一个命令的结果作为后续命令的参数进行输入,也有tee管道,可以进行多次筛选,即多次使用|过滤命令。 重定向 文件描述符FD Linux中输入输出分为三种…...

kotlin数组
1、kotlin中的数组与java数组比较: 2、创建 fun main() {// 值创建val a intArrayOf(1,2,3)// 表达式创建val b IntArray(3){println("it: ${it}")it1}println("a数组:${a.contentToString()}, 长度:${a.size}")prin…...

SpringSecurity实战入门——认证
项目代码 gson/spring-security-demo 简介 Spring Security 是 Spring 家族中的一个安全管理框架。相比与另外一个安全框架Shiro,它提供了更丰富的功能,社区资源也比Shiro丰富。 一般来说中大型的项目都是使用SpringSecurity来做安全框架。小项目有Shiro的比较多,因为相比…...

23种设计模式之桥接模式
桥接模式 1、定义 桥接模式:将抽象部分与它的实现部分解耦,使得两者都能独立变化 2、桥接模式结构 Abstraction(抽象类):它是用于定义抽象类的,通常是抽象类而不是接口,其中定义了一个Imple…...

vuejs3+elementPlus后台管理系统,左侧菜单栏制作、跳转、默认激活菜单
制作: <script setup> import {useUserStore} from "/stores/userStore.js"; import {ref} from "vue";const userStore useUserStore() //默认激活菜单 const defaultMenu ref(/home) </script><template><el-menuact…...
代码随想录算法训练营第四十四天|LeetCode198 打家劫舍、LeetCode213 打家劫舍Ⅱ
题1: 指路:198. 打家劫舍 - 力扣(LeetCode) 思路与代码: 对于这个题,拿房屋i举例,我们需要考虑的是否确定偷取这个房屋,如果确定偷取这个房屋,那么我们将得到房屋i的金…...

Git进阶使用(图文详解)
文章目录 Git概述Git基础指令Git进阶使用一、Git分支1.主干分支2.其他分支2.1创建分支2.2查看分支1. 查看本地分支2. 查看远程分支3. 查看本地和远程分支4. 显示分支的详细信息5. 查看已合并和未合并的分支 2.3切换分支1. 切换到已有的本地分支2. 创建并切换到新分支3. 切换到远…...
Effective C++ 改善程序与设计的55个具体做法笔记与心得 4
四. 设计与声明 18. 让接口容易被正确使用,不易被误用 请记住: 好的接口很容易被正确使用,不容易被误用。你应该在你的所有接口中努力达成这些性质“促进正确使用”的办法包括接口的一致性,以及与内置类型的行为兼容。“阻止误…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...

如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...
Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换
目录 关键点 技术实现1 技术实现2 摘要: 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式(自动驾驶、人工驾驶、远程驾驶、主动安全),并通过实时消息推送更新车…...

实战三:开发网页端界面完成黑白视频转为彩色视频
一、需求描述 设计一个简单的视频上色应用,用户可以通过网页界面上传黑白视频,系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观,不需要了解技术细节。 效果图 二、实现思路 总体思路: 用户通过Gradio界面上…...
SQL Server 触发器调用存储过程实现发送 HTTP 请求
文章目录 需求分析解决第 1 步:前置条件,启用 OLE 自动化方式 1:使用 SQL 实现启用 OLE 自动化方式 2:Sql Server 2005启动OLE自动化方式 3:Sql Server 2008启动OLE自动化第 2 步:创建存储过程第 3 步:创建触发器扩展 - 如何调试?第 1 步:登录 SQL Server 2008第 2 步…...
【深尚想】TPS54618CQRTERQ1汽车级同步降压转换器电源芯片全面解析
1. 元器件定义与技术特点 TPS54618CQRTERQ1 是德州仪器(TI)推出的一款 汽车级同步降压转换器(DC-DC开关稳压器),属于高性能电源管理芯片。核心特性包括: 输入电压范围:2.95V–6V,输…...
JavaScript 标签加载
目录 JavaScript 标签加载script 标签的 async 和 defer 属性,分别代表什么,有什么区别1. 普通 script 标签2. async 属性3. defer 属性4. type"module"5. 各种加载方式的对比6. 使用建议 JavaScript 标签加载 script 标签的 async 和 defer …...

Selenium 查找页面元素的方式
Selenium 查找页面元素的方式 Selenium 提供了多种方法来查找网页中的元素,以下是主要的定位方式: 基本定位方式 通过ID定位 driver.find_element(By.ID, "element_id")通过Name定位 driver.find_element(By.NAME, "element_name"…...