当前位置: 首页 > article >正文

Spring Boot 中的重试机制

@Retryable 注解简介

@Retryable 注解是 Spring Retry 模块提供的,用于自动重试可能会失败的方法。在微服务架构和分布式系统中,服务之间的调用可能会因为网络问题、服务繁忙等原因失败。使用 @Retryable 可以提高应用的稳定性和容错能力 1。

使用步骤

(1)添加依赖

首先,确保你的 Spring Boot 项目中包含了 spring-retry 依赖。如果使用 Maven,可以在 pom.xml 文件中添加以下依赖:

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

(2)启用重试

在 Spring Boot 应用的主类或配置类上添加 @EnableRetry 注解,启用重试功能 16。

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.retry.annotation.EnableRetry;@SpringBootApplication
@EnableRetry
public class MyApplication {public static void main(String[] args) {SpringApplication.run(MyApplication.class, args);}
}

(3)使用 @Retryable 注解

在需要进行重试的方法上添加 @Retryable 注解。

import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;@Service
public class MyService {@Retryable(value = {MyNetworkException.class}, maxAttempts = 3)public String fetchDataFromRemote() {System.out.println("尝试调用远程服务...");// 模拟可能失败的远程调用if (Math.random() < 0.5) {throw new MyNetworkException("网络异常");}return "调用成功";}
}

在这个例子中,fetchDataFromRemote 方法在抛出 MyNetworkException 异常时会进行重试,最多重试 3 次。

@Retryable 注解的属性

@Retryable 注解提供了多个属性,用于配置重试策略 1。

  • value / exception

    指定需要重试的异常类型。可以指定一个或多个异常类。

    @Retryable(value = {MyNetworkException.class, TimeoutException.class})
    public String fetchDataFromRemote() {// ...
    }
  • maxAttempts

    指定最大重试次数,包括第一次调用。默认值为 3。

    @Retryable(value = MyNetworkException.class, maxAttempts = 5)
    public String fetchDataFromRemote() {// ...
    }
  • backoff

    指定重试之间的退避策略。可以使用 @Backoff 注解配置退避策略。

    • delay:重试之间的延迟时间,单位为毫秒。
    • multiplier:延迟倍数,用于实现指数退避。
    • random:是否在延迟时间上增加一个随机值,以避免多个服务同时重试。
    import org.springframework.retry.annotation.Backoff;@Retryable(value = MyNetworkException.class, backoff = @Backoff(delay = 2000, multiplier = 1.5))
    public String fetchDataFromRemote() {// ...
    }

    在这个例子中,第一次重试延迟 2 秒,第二次重试延迟 3 秒 (2 * 1.5),以此类推。

@Recover 注解

@Recover 注解用于指定重试失败后的恢复方法。恢复方法的参数必须与重试方法抛出的异常类型相匹配,并且必须在同一个类中。

import org.springframework.retry.annotation.Recover;@Service
public class MyService {@Retryable(value = {MyNetworkException.class}, maxAttempts = 3)public String fetchDataFromRemote() {System.out.println("尝试调用远程服务...");// 模拟可能失败的远程调用if (Math.random() < 0.5) {throw new MyNetworkException("网络异常");}return "调用成功";}@Recoverpublic String recover(MyNetworkException e) {System.out.println("重试失败,执行恢复逻辑...");// 处理异常的逻辑,例如返回默认值或记录日志return "默认值";}
}

在这个例子中,如果 fetchDataFromRemote 方法重试 3 次后仍然失败,会调用 recover 方法处理 MyNetworkException 异常。

  • 第一个参数必须是 Throwable 类型或其子类型:

    • @Recover 方法的第一个参数必须是 Throwable 类型,或者 @Retryable 方法中声明的异常类型(或其父类)。
    • 这个参数用于接收 @Retryable 方法抛出的异常。
  • 后续参数必须与 @Retryable 方法的参数类型和顺序一致:

    • @Recover 方法的后续参数必须与对应的 @Retryable 方法的参数类型和顺序完全一致。
    • 这些参数用于将 @Retryable 方法的参数传递给 @Recover 方法。
  • 参数数量:

    • @Recover 方法的参数数量必须等于 @Retryable 方法的参数数量加 1(用于接收异常)。

当被 @Retryable 注解的方法经过多次重试都失败,并且成功调用了 @Recover 注解的恢复方法后,最初调用 @Retryable 方法的方法会拿到 @Recover 方法的返回值

  1. 初始调用: 外部方法调用被 @Retryable 注解的方法。
  2. 重试失败: @Retryable 方法执行失败,并且经过配置的重试次数后仍然失败。
  3. 调用 @Recover Spring Retry 框架会自动查找并调用与 @Retryable 方法签名匹配的 @Recover 方法。
  4. 返回结果: @Recover 方法执行完毕后,会将它的返回值返回给最初调用 @Retryable 方法的外部方法。

关键点:

  • @Recover 方法的返回值类型必须与 @Retryable 方法的返回值类型相同,这样才能保证类型安全。
  • 如果 @Recover 方法本身也抛出了异常,那么这个异常会直接抛给最初的调用者,不会再进行重试。

如果你没有定义 @Recover 注解的方法,并且 @Retryable 注解的方法在经过所有重试次数后仍然失败,那么最初调用 @Retryable 方法的地方会抛出 RetryException 异常

具体流程如下:

  1. 初始调用: 外部方法调用被 @Retryable 注解的方法。
  2. 重试失败: @Retryable 方法执行失败,并且经过配置的重试次数后仍然失败。
  3. 没有 @Recover 方法: Spring Retry 框架找不到与 @Retryable 方法签名匹配的 @Recover 方法。
  4. 抛出 RetryException Spring Retry 框架会抛出一个 RetryException 异常,该异常会传递给最初调用 @Retryable 方法的外部方法。

相关文章:

Spring Boot 中的重试机制

Retryable 注解简介 Retryable 注解是 Spring Retry 模块提供的&#xff0c;用于自动重试可能会失败的方法。在微服务架构和分布式系统中&#xff0c;服务之间的调用可能会因为网络问题、服务繁忙等原因失败。使用 Retryable 可以提高应用的稳定性和容错能力 1。 使用步骤 &…...

【React中useRef钩子详解】

一、useRef的核心特性 useRef是React提供的Hook,用于在函数组件中创建可变的持久化引用,具有以下核心特性: 持久化存储 返回的ref对象在组件整个生命周期内保持不变,即使组件重新渲染,current属性的值也不会丢失。无触发渲染 修改ref.current的值不会导致组件重新渲染,适…...

golang-ErrGroup用法以及源码解读笔记

介绍 ErrGroup可以并发执行多个goroutine&#xff0c;并可以很方便的处理错误 与sync.WaitGroup相比 错误处理 sync.WaitGroup只负责等待goroutine执行完成&#xff0c;而不处理返回值或者错误errgroup.Group目前虽然不能直接处理函数的返回值或错误。但是当goroutine返回错…...

17.【.NET 8 实战--孢子记账--从单体到微服务--转向微服务】--微服务基础工具与技术--loki

在微服务中&#xff0c;日志是非常重要的组成部分。它不仅可以帮助我们排查问题&#xff0c;还可以帮助我们分析系统的性能和使用情况。 一、loki简介 loki是一个开源的日志聚合系统&#xff0c;它可以帮助我们高效地收集、存储和分析日志数据。loki的设计理念是“简单、快速…...

CVPR计算机视觉顶会论文解读:IPC-Dehaze 如何解决真实场景去雾难题

【CVPR 2025】迭代预测-评判编解码网络&#xff1a;突破真实场景去雾的极限 摘要 本文提出了一种名为IPC-Dehaze的创新去雾方法&#xff0c;通过迭代预测-评判框架和码本解码机制&#xff0c;有效解决了现有去雾算法在复杂场景下的性能瓶颈。该方法在多个基准测试中取得了SOT…...

ppy/osu构建 ipad作为osu按键xz笔记2 deepwiki websokect

ipad当x和z键玩osu #无声打osu#没磁轴怎么打osu 下载 .NET (Linux、macOS 和 Windows) | .NET dotnet还行 构建&#xff1a;f5 运行&#xff1a;dotnet run --project osu.Desktop -c Debug deepwiki就是nb uinput是ubuntu的我现在没法调试&#xff0c;放着 import asyn…...

scons user 3.1.2

前言 感谢您抽出时间阅读有关 SCons 的内容。SCons 是一款下一代软件构建工具&#xff0c;或者称为 make 工具&#xff0c;即一种用于构建软件&#xff08;或其他文件&#xff09;并在底层输入文件发生更改时使已构建的软件保持最新状态的软件实用程序。 SCons 最显著的特点是…...

大语言模型主流架构解析:从 Transformer 到 GPT、BERT

&#x1f4cc; 友情提示&#xff1a; 本文内容由银河易创AI&#xff08;https://ai.eaigx.com&#xff09;创作平台的gpt-4-turbo模型生成&#xff0c;旨在提供技术参考与灵感启发。文中观点或代码示例需结合实际情况验证&#xff0c;建议读者通过官方文档或实践进一步确认其准…...

.NET程序启动就报错,如何截获初期化时的问题json

一&#xff1a;背景 1. 讲故事 前几天训练营里的一位朋友在复习课件的时候&#xff0c;程序一跑就报错&#xff0c;截图如下&#xff1a; 从给出的错误信息看大概是因为json格式无效导致的&#xff0c;在早期的训练营里曾经也有一例这样的报错&#xff0c;最后定位下来是公司…...

nacos:服务注册原理

目录 NaCos服务注册原理1、AbstractAutoServiceRegistration功能和作用onApplicationEvent()方法start()方法 2、NacosAutoServiceRegistration功能和作用NacosAutoServiceRegistration.register()方法AbstractAutoServiceRegistration.register()方法 3、NacosServiceRegistry…...

基于开源AI大模型与S2B2C生态的个人品牌优势挖掘与标签重构研究

摘要&#xff1a;在数字文明时代&#xff0c;个人品牌塑造已从传统经验驱动转向数据智能驱动。本文以开源AI大模型、AI智能名片与S2B2C商城小程序源码为技术载体&#xff0c;提出"社会评价-数据验证-标签重构"的三维分析框架。通过实证研究发现&#xff0c;结合第三方…...

《React Native与Flutter:社交应用中用户行为分析与埋点统计的深度剖析》

React Native与Flutter作为两款备受瞩目的跨平台开发框架&#xff0c;正深刻地影响着应用的构建方式。当聚焦于用户行为分析与埋点统计时&#xff0c;它们各自展现出独特的策略与工具选择&#xff0c;这些差异和共性不仅关乎开发效率&#xff0c;更与社交应用能否精准把握用户需…...

polarctf-web-[简单rce]

考点&#xff1a; (1)RCE(eval函数) (2)执行函数(passthru函数) (3)/顶级(根)目录查看 (4)sort排序查看函数 题目来源&#xff1a;Polarctf-web-[简单rce] 解题&#xff1a; 代码审计 <?php/*​PolarD&N CTF​*/highlight_file(__FILE__);function no($txt){ # …...

深入理解 Cortex-M3 特殊寄存器

在上一篇文章中分享了 Cortex-M3 内核寄存器组的相关知识&#xff0c;实际上除了内核寄存器组外&#xff0c;CM3 处理器中还存在多个特殊寄存器&#xff0c;它们分别为 程序状态寄存器&#xff0c;中断/异常屏蔽寄存器 和 控制寄存器。 需要注意的是&#xff0c;特殊寄存器未经…...

[Java实战]Spring Boot 3 整合 Ehcache 3(十九)

[Java实战]Spring Boot 3 整合 Ehcache 3&#xff08;十九&#xff09; 引言 在微服务和高并发场景下&#xff0c;缓存是提升系统性能的关键技术之一。Ehcache 作为 Java 生态中成熟的内存缓存框架&#xff0c;其 3.x 版本在性能、功能和易用性上均有显著提升。本文将详细介绍…...

建筑物渗水漏水痕迹发霉潮湿分割数据集labelme格式1357张1类别

数据集中有增强图片详情看图片 数据集格式&#xff1a;labelme格式(不包含mask文件&#xff0c;仅仅包含jpg图片和对应的json文件) 图片数量(jpg文件个数)&#xff1a;1357 标注数量(json文件个数)&#xff1a;1357 标注类别数&#xff1a;1 标注类别名称:["water&qu…...

Doris和Clickhouse对比

目录 一、Doris和Clickhouse对比1. 底层架构**DorisClickHouse** 2. 运行原理DorisClickHouse 3. 使用场景DorisClickHouse 4. 优缺点对比总结 二、MPP架构和Shared-Nothing 架构对比1. 什么是 MPP 架构&#xff1f;定义特点典型代表 2. 什么是 Shared-Nothing 架构&#xff1f…...

第二十二天打卡

数据预处理 import pandas as pd from sklearn.model_selection import train_test_splitdef data_preprocessing(file_path):"""泰坦尼克号生存预测数据预处理函数参数:file_path: 原始数据文件路径返回:preprocessed_data: 预处理后的数据集""&quo…...

Android Activity之间跳转的原理

一、Activity跳转核心流程‌ Android Activity跳转的底层实现涉及 ‌系统服务交互‌、‌进程间通信&#xff08;IPC&#xff09;‌ 和 ‌生命周期管理‌&#xff0c;主要流程如下&#xff1a; ‌startActivity() 触发请求‌ 应用调用 startActivity() 时&#xff0c;通过 Inst…...

MATLAB 矩阵与数组操作基础教程

文章目录 前言环境配置一、创建矩阵与数组&#xff08;一&#xff09;直接输入法&#xff08;二&#xff09;特殊矩阵生成函数&#xff08;三&#xff09;使用冒号表达式创建数组 二、矩阵与数组的基本操作&#xff08;一&#xff09;访问元素&#xff08;二&#xff09;修改元…...

【Linux】第十六章 分析和存储日志

1. RHEL 日志文件保存在哪个目录中&#xff1f; 一般存储在 /var/log 目录中。 2. 什么是syslog消息和非syslog消息&#xff1f; syslog消息是一种标准的日志记录协议和格式&#xff0c;用于系统和应用程序记录日志信息。它规定了日志消息的结构和内容&#xff0c;包括消息的…...

解锁性能密码:Linux 环境下 Oracle 大页配置全攻略​

在 Oracle 数据库运行过程中&#xff0c;内存管理是影响其性能的关键因素之一。大页内存&#xff08;Large Pages&#xff09;作为一种优化内存使用的技术&#xff0c;能够显著提升 Oracle 数据库的运行效率。本文将深入介绍大页内存的相关概念&#xff0c;并详细阐述 Oracle 在…...

Spark,在shell中运行RDD程序

在hdfs中/wcinput中创建一个文件&#xff1a;word2.txt在里面写几个单词 启动hdfs集群 [roothadoop100 ~]# myhadoop start [roothadoop100 ~]# cd /opt/module/spark-yarn/bin [roothadoop100 ~]# ./spark-shell 写个11测试一下 按住ctrlD退出 进入环境&#xff1a;spa…...

SAP学习笔记 - 开发11 - RAP(RESTful Application Programming)简介

上一章学习了BTP架构图&#xff0c;实操创建Directory/Subaccount&#xff0c;BTP的内部组成&#xff0c;BTP Cockpit。 SAP学习笔记 - 开发10 - BTP架构图&#xff0c;实操创建Directory/Subaccount&#xff0c;BTP的内部组成&#xff0c;BTP Cockpit-CSDN博客 本章继续学习S…...

数据防泄密安全:企业稳健发展的守护盾

在数字化时代&#xff0c;数据已成为企业最核心的资产之一。无论是客户信息、财务数据&#xff0c;还是商业机密&#xff0c;一旦泄露&#xff0c;都可能给企业带来不可估量的损失。近年来&#xff0c;数据泄露事件频发&#xff0c;如Facebook用户数据泄露、Equifax信用数据外泄…...

MySQL之基础索引

目录 引言 1、创建索引 2、索引的原理 2、索引的类型 3、索引的使用 1.添加索引 2.删除索引 3.删除主键索引 4.修改索引 5.查询索引 引言 当一个数据库里面的数据特别多&#xff0c;比如800万&#xff0c;光是创建插入数据就要十几分钟&#xff0c;我们查询一条信息也…...

Openshift节点Disk pressure

OpenShift 监控以下指标&#xff0c;并定义以下垃圾回收的驱逐阈值。请参阅产品文档以更改任何驱逐值。 nodefs.available 从 cadvisor 来看&#xff0c;该node.stats.fs.available指标表示节点文件系统&#xff08;所在位置&#xff09;上有多少可用&#xff08;剩余&#xf…...

拉丁方分析

本文是实验设计与分析&#xff08;第6版&#xff0c;Montgomery著傅珏生译)第4章随机化区组&#xff0c;拉丁方&#xff0c;以及有关的设计第4.2节的python解决方案。本文尽量避免重复书中的理论&#xff0c;着于提供python解决方案&#xff0c;并与原书的运算结果进行对比。您…...

Pomelo知识框架

一、Pomelo 基础概念 Pomelo 简介 定位&#xff1a;分布式游戏服务器框架&#xff08;网易开源&#xff09;。 特点&#xff1a;高并发、可扩展、多进程架构、支持多种通信协议&#xff08;WebSocket、TCP等&#xff09;。 适用场景&#xff1a;MMO RPG、实时对战、社交游戏等…...

软考软件设计师中级——软件工程笔记

1.软件过程 1.1能力成熟度模型&#xff08;CMM&#xff09; 软件能力成熟度模型&#xff08;CMM&#xff09;将软件过程改进分为以下五个成熟度级别&#xff0c;每个级别都定义了特定的过程特征和目标&#xff1a; 初始级 (Initial)&#xff1a; 软件开发过程杂乱无章&#xf…...