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

SpringBoot:SpringBoot中调用失败如何重试

一、引言

  在实际的应用中,我们经常需要调用第三方API来获取数据或执行某些操作。然而,由于网络不稳定、第三方服务异常等原因,API调用可能会失败。为了提高系统的稳定性和可靠性,我们通常会考虑实现重试机制。

  Spring Retry为Spring应用程序提供了方法级别的重试机制,帮助开发者处理由于网络不稳定、服务不可用、数据库临时性问题、外部依赖故障等原因导致的瞬时性故障。通过配置重试策略,可以确保应用程序在特定情况下能够自动进行重试,从而提高系统的健壮性和可用性。

  本文将深入探讨如何在Spring Boot项目中优雅地使用Spring Retry重试调用第三方API,并结合代码示例,展示具体实现方式。

二、重试机制的必要性

  提高系统的可用性:在网络通信、数据库操作、远程服务调用等场景中,由于网络抖动、服务暂时不可用或超时等原因,单次操作可能会失败。引入重试机制可以在这些情况下自动重新尝试操作,从而提高系统的可用性和容错能力。

  优化用户体验:对于用户来说,遇到操作失败时,他们期望系统能够自动处理并恢复,而不是需要他们手动重新尝试。重试机制可以在用户无感知的情况下自动进行,从而提供更好的用户体验。

  减少人工干预:在没有重试机制的情况下,一旦操作失败,可能需要人工进行干预和修复。这不仅增加了运维成本,而且可能导致响应延迟。重试机制可以自动处理大多数可恢复的失败情况,减少人工干预的需要。

  降低故障率:有些故障是暂时的,例如网络短暂中断或数据库连接超时。在这种情况下,立即重试操作很可能会成功。重试机制可以在这些情况下自动重试,从而降低故障率。

三、使用场景

  远程调用和网络通信:由于网络不稳定或服务不可用,可能会出现连接问题,Spring Retry可以帮助处理这类问题。

  数据库交互:执行SQL查询或更新操作时,数据库服务器可能会出现临时性的问题,如死锁或连接丢失,Spring Retry可以提供重试机制。

  外部依赖:如果应用程序依赖于外部服务、硬件设备或其他不可控因素,而这些依赖可能会偶尔出现故障或不可用状态,Spring Retry可以确保应用程序能够自动进行重试。

  并发控制:在多线程环境中,可能会出现竞争条件或并发问题,导致某些操作失败,Spring Retry可以帮助处理这类并发问题。

  复杂的业务逻辑:某些业务逻辑可能需要多次尝试才能成功,Spring Retry提供了重试机制来支持这类业务逻辑。

四、Spring Retry在项目中应用

1. 添加依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency><dependency><groupId>org.springframework.retry</groupId><artifactId>spring-retry</artifactId>
</dependency>

2. 在需要重试的方法上添加@Retryable注解,并指定可重试的异常类型、最大重试次数等参数

@Retryable(value = {SomeException.class}, maxAttempts = 2, backoff = @Backoff(delay = 2000))
@Overridepublic void testRetry() {// 业务场景System.out.println("执行业务了...");// 模拟执行可能会失败的操作 ...throw new SomeException("run failed"); // 示例:抛出异常以触发重试}// 定义自定义异常类(如果需要)public static class SomeException extends RuntimeException {public SomeException(String message) {super(message);}}
@RestController
public class RetryController {@Autowiredprivate RetryService retryService;@RequestMapping("/retry/test")public Object retryTest() {retryService.testRetry();return "success";}
}

3. 运行结果

在这里插入图片描述
4. 注解说明

@Retryable 注解

  value:可重试的异常类型。含义同include。默认为空(如果excludes也为空,则重试所有异常)

  include:可重试的异常类型。默认为空(如果excludes也为空,则重试所有异常)

  exclude:无需重试的异常类型。默认为空(如果includes也为空,则重试所有异常)

  maxAttempts:最大重试次数(包括第一次失败),默认为3次

  backoff:重试等待策略,下面会在@Backoff中介绍

  recover:表示重试次数到达最大重试次数后的回调方法

@Backoff 注解

value
  默认为1000L,重试之间的基础延迟时间(以毫秒为单位)。当没有设置 delay时,value将作为首次重试的延迟时间。之后,如果multiplier不为0,则后续的延迟时间会根据 value和multiplier来计算

delay
  默认为0,首次重试之前的延迟时间(以毫秒为单位)。如果设置为0,则不等待直接进行首次重试。如果同时设置了value和delay,则delay优先。

maxDelay
  默认为0,重试之间延迟时间的上限(以毫秒为单位)。如果计算出的延迟时间超过了这个值,则实际的延迟时间将被限制为maxDelay。这个参数用于防止延迟时间无限增长,从而避免过长的等待时间。

multipler
  默认为0.0。用于计算递增等待时间的乘数。例如,如果设置为1.5,则每次重试的等待时间将是前一次的1.5倍。
  示例:backoff = @Backoff(delay = 200, multiplier = 1.5),在这个例子中,首次重试会等待200毫秒,第二次会等待300毫秒(200毫秒1.5),第三次会等待450毫秒(300毫秒1.5),以此类推。

delayExpression
  评估标准退避期的表达式。在指数情况下用作初始值*,在均匀情况下用作最小值。覆盖 delay。

maxDelayExpression
  该表达式计算重试之间的最大等待时间(以毫秒为单位)。 如果小于delay,那么将应用30000L为默认值。覆盖maxDelay。

multiplierExpression
  评估为用作乘数的值,以生成退避的下一个延迟。覆盖multiplier。 返回一个乘数表达式,用于计算下一个退避延迟

random
  默认为false,在指数情况下multiplier > 0将此值设置为true可以使后退延迟随机化,从而使最大延迟乘以前一延迟,并且两个值之间的分布是均匀的。

五、重试还是失败,如何解决?

除了重试,我们可能还希望在多次重试失败后执行降级操作,以避免一直等待不确定的恢复时间。

@Recover注解

可以使用@Recover注解来指定一个方法来处理所有由@Retryable注解标注的方法抛出的异常。当重试次数耗尽后,会调用这个方法

 @Recoverpublic void recover(SomeException e) {// 处理重试失败后的逻辑System.out.println("recover from " + e.getMessage());}

注意

由于Spring Retry用到了aspect增强,所有会有aspect的坑,就是方法内部调用,会使aspect增强失效,那么retry当然也会失效

public void A(){B();
}//这里B不会执行
@Retryable(value = {SomeException.class}, maxAttempts = 2, backoff = @Backoff(delay = 2000))
public void B(){throw new SomeException("run failed");
}

  @Recover 注解来开启重试失败后调用的方法(注意,需跟重处理方法在同一个类中),此注解注释的方法参数一定要是 @Retryable 抛出的异常,否则无法识别。

六、重试当中的策略

1. @Backoff 的参数会影响我们使用哪种退避策略

  FixedBackOffPolicy:默认退避策略,每1秒重试1次

  ExponentialBackOffPolicy:指数退避策略,当设置multiplier时使用,每次重试时间间隔为 当前延迟时间 * multiplier。

  例如:默认初始1秒,系数是2,那么下次延迟2秒,再下次就是延迟4秒,如此类推,最大30秒。

  ExponentialRandomBackOffPolicy:指数随机退避策略。在指数退避策略的基础上增加了随机性。

  UniformRandomBackOffPolicy:均匀随机策略,设置maxDely但没有设置multiplier时使用,重试间隔会在maxDelay和delay间随机

2. 重试策略

  SimpleRetryPolicy:默认最多重试 3 次

  TimeoutRetryPolicy:默认在 1 秒内失败都会重试

  ExpressionRetryPolicy:符合表达式就会重试

  CircuitBreakerRetryPolicy:增加了熔断的机制,如果不在熔断状态,则允许重试

  CompositeRetryPolicy:可以组合多个重试策略

  NeverRetryPolicy:从不重试(也是一种重试策略哈)

  AlwaysRetryPolicy:总是重试

3. RetryTemplate提供了更为灵活的重试控制

  了解了重试策略,当我们使用RetryTemplate模式的时候,可以更加灵活的重试控制

@Configuration
@EnableRetry
public class RetryConfig {@Beanpublic RetryTemplate retryTemplate() {SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();retryPolicy.setMaxAttempts(3);FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();backOffPolicy.setBackOffPeriod(1000);RetryTemplate retryTemplate = new RetryTemplate();retryTemplate.setRetryPolicy(retryPolicy);retryTemplate.setBackOffPolicy(backOffPolicy);return retryTemplate;}
}
 public Object executeWithRetry() throws Exception{return retryTemplate.execute(new RetryCallback<Object, Exception>() {@Overridepublic Object doWithRetry(RetryContext context) throws Exception {// 这里放置可能会失败的操作// 例如,调用远程服务或执行数据库操作// ...// 模拟失败if (true) {throw new RuntimeException("Operation failed");}// 如果成功,则返回结果return "success";}});}

  在Spring Boot项目中,通过集成Spring Retry模块,我们可以优雅地实现对第三方API调用的重试机制。通过@Retryable注解,我们能够很方便地在方法级别上添加重试策略。

相关文章:

SpringBoot:SpringBoot中调用失败如何重试

一、引言 在实际的应用中&#xff0c;我们经常需要调用第三方API来获取数据或执行某些操作。然而&#xff0c;由于网络不稳定、第三方服务异常等原因&#xff0c;API调用可能会失败。为了提高系统的稳定性和可靠性&#xff0c;我们通常会考虑实现重试机制。 Spring Retry为Spri…...

2024-06-24 问AI: 在大语言模型中,什么是ray?

文心一言 在大语言模型中&#xff0c;Ray是一个开源的统一框架&#xff0c;用于扩展AI和Python应用程序&#xff0c;特别是在机器学习领域。以下是关于Ray的详细解释&#xff1a; 核心功能&#xff1a; Ray为并行处理提供了计算层&#xff0c;使得用户无需成为分布式系统专家…...

仓库管理系统09--修改用户密码

1、添加窗体 2、窗体布局控件 UI设计这块还是传统的表格布局&#xff0c;采用5行2列 3、创建viewmodel 4、前台UI绑定viewmodel 这里要注意属性绑定和命令绑定及命令绑定时传递的参数 <Window x:Class"West.StoreMgr.Windows.EditPasswordWindow"xmlns"http…...

在Spring Data JPA中使用@Query注解

目录 前言示例简单示例只查询部分字段&#xff0c;映射到一个实体类中只查询部分字段时&#xff0c;也可以使用List<Object[]>接收返回值再复杂一些 前言 在以往写过几篇spring data jpa相关的文章&#xff0c;分别是 Spring Data JPA 使用JpaSpecificationExecutor实现…...

【UE5.1】Chaos物理系统基础——01 创建可被破坏的物体

目录 步骤 一、通过笔刷创建静态网格体 二、破裂静态网格体 三、“统一” 多层级破裂 四、“簇” 群集化的破裂 五、几何体集的材质 六、防止几何体集自动破碎 步骤 一、通过笔刷创建静态网格体 1. 可以在Quixel Bridge中下载两个纹理&#xff0c;用于表示石块的内外纹…...

Linux下SUID提权学习 - 从原理到使用

目录 1. 文件权限介绍1.1 suid权限1.2 sgid权限1.3 sticky权限 2. SUID权限3. 设置SUID权限4. SUID提权原理5. SUID提权步骤6. 常用指令的提权方法6.1 nmap6.2 find6.3 vim6.4 bash6.5 less6.6 more6.7 其他命令的提权方法 1. 文件权限介绍 linux的文件有普通权限和特殊权限&a…...

Redis主从复制搭建一主多从

1、创建/myredis文件夹 2、复制redis.conf配置文件到新建的文件夹中 3、配置一主两从&#xff0c;创建三个配置文件 ----redis6379.conf ----redis6380.conf ----redis6381.conf 4、在三个配置文件写入内容 redis6379.conf里面的内容 include /myredis/redis.conf pidfile /va…...

GPT-4o文科成绩超一本线,理科为何表现不佳?

目录 01 评测榜单 02 实际效果 什么&#xff1f;许多大模型的文科成绩竟然超过了一本线&#xff0c;还是在竞争激烈的河南省&#xff1f; 没错&#xff0c;最近有一项大模型“高考大摸底”评测引起了广泛关注。 河南高考文科今年的一本线是521分&#xff0c;根据这项评测&…...

Lombok的hashCode方法

Lombok对于重写hashCode的算法真的是很经典&#xff0c;但是目前而言有一个令人难以注意到的细节。在继承关系中&#xff0c;父类的hashCode针对父类的所有属性进行运算&#xff0c;而子类的hashCode却只是针对子类才有的属性进行运算&#xff0c;立此贴提醒自己。 目前重写ha…...

关于springboot创建kafkaTopic

工具类提供&#xff0c;方法名见名知意。使用kafka admin import org.apache.kafka.clients.admin.*; import org.apache.kafka.common.KafkaFuture;import java.util.*; import java.util.concurrent.ExecutionException;import org.apache.kafka.clients.admin.AdminClient; …...

OOAD的概念

面向对象分析与设计&#xff08;OOAD, Object-Oriented Analysis and Design&#xff09;是一种软件开发方法&#xff0c;它利用面向对象的概念和技术来分析和设计软件系统。OOAD 主要关注对象、类以及它们之间的关系&#xff0c;通过抽象、封装、继承和多态等面向对象的基本原…...

Day47

Day47 手写Spring-MVC之DispatcherServlet DispatcherServlet的思路&#xff1a; 前端传来URI&#xff0c;在TypeContainer容器类中通过uri得到对应的类描述类对象&#xff08;注意&#xff1a;在监听器封装类描述类对象的时候&#xff0c;是针对于每一个URI进行封装的&#x…...

【面试系列】后端开发工程师 高频面试题及详细解答

欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;欢迎订阅相关专栏&#xff1a; ⭐️ 全网最全IT互联网公司面试宝典&#xff1a;收集整理全网各大IT互联网公司技术、项目、HR面试真题. ⭐️ AIGC时代的创新与未来&#xff1a;详细讲解AIGC的概念、核心技术、…...

mac|浏览器链接不上服务器但可以登微信

千万千万千万不要没有关梯子直接关机&#xff0c;不然就会这样子呜呜呜 设置-网络&#xff0c;点击三个点--选择--位置--编辑位置&#xff08;默认是自动&#xff09; 新增一个&#xff0c;然后选中点击完成 这样就可以正常上网了...

Spring Cloud Alibaba之负载均衡组件Ribbon

一、什么是负载均衡&#xff1f; &#xff08;1&#xff09;概念&#xff1a; 在基于微服务架构开发的系统里&#xff0c;为了能够提升系统应对高并发的能力&#xff0c;开发人员通常会把具有相同业务功能的模块同时部署到多台的服务器中&#xff0c;并把访问业务功能的请求均…...

tkinter显示图片

tkinter显示图片 效果代码解析打开和显示图像 代码 效果 代码解析 打开和显示图像 def open_image():file_path filedialog.askopenfilename(title"选择图片", filetypes(("PNG文件", "*.png"), ("JPEG文件", "*.jpg;*.jpeg&q…...

000.二分查找算法题解目录

000.二分查找算法题解目录 69. x 的平方根&#xff08;简单&#xff09;34. 在排序数组中查找元素的第一个和最后一个位置&#xff08;中等&#xff09;...

数据资产赋能企业决策:通过精准的数据分析和洞察,构建高效的数据资产解决方案,为企业提供决策支持,助力企业实现精准营销、风险管理、产品创新等目标,提升企业竞争力

一、引言 在信息化和数字化飞速发展的今天&#xff0c;数据已成为企业最宝贵的资产之一。数据资产不仅包含了企业的基本信息&#xff0c;还蕴含了丰富的市场趋势、消费者行为和潜在商机。如何通过精准的数据分析和洞察&#xff0c;构建高效的数据资产解决方案&#xff0c;为企…...

【java开发环境】多版本jdk 自由切换window和linux

win10 一、准备 各种版本的jdk&#xff0c;按自己的需要下载。 我这里是需要jdk17和jdk8。 1、jdk17 下载&#xff1a;Java Downloads | Oracle&#xff0c;选择exe后缀文件 2、jdk8下 载&#xff1a;Java Downloads | Oracle&#xff0c;选择exe后缀文件 二、详细步骤 1、…...

MySQL实训项目——餐饮点餐系统

项目简介&#xff1a;餐饮点餐系统是一款为餐厅和顾客提供便捷点餐服务的在线平台。通过该系统&#xff0c;餐厅能够展示其菜单&#xff0c;顾客可以浏览菜品&#xff0c;并将其加入购物车或直接下单。系统还提供了订单管理功能&#xff0c;方便餐厅跟踪和处理顾客的订单。 1. …...

label-studio的使用教程(导入本地路径)

文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

Spring AI 入门:Java 开发者的生成式 AI 实践之路

一、Spring AI 简介 在人工智能技术快速迭代的今天&#xff0c;Spring AI 作为 Spring 生态系统的新生力量&#xff0c;正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务&#xff08;如 OpenAI、Anthropic&#xff09;的无缝对接&…...

网络编程(UDP编程)

思维导图 UDP基础编程&#xff08;单播&#xff09; 1.流程图 服务器&#xff1a;短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中&#xff0c;我们渴望一个能激发创想、愉悦感官的工作与生活伙伴&#xff0c;它不仅是冰冷的科技工具&#xff0c;更能触动我们内心深处的细腻情感。正是在这样的期许下&#xff0c;华硕a豆14 Air香氛版翩然而至&#xff0c;它以一种前所未有的方式&#x…...

WebRTC从入门到实践 - 零基础教程

WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC&#xff1f; WebRTC&#xff08;Web Real-Time Communication&#xff09;是一个支持网页浏览器进行实时语音…...

Linux知识回顾总结----进程状态

本章将会介绍进程的一些概念&#xff1a;冯诺伊曼体系结构、进程是什么&#xff0c;怎么用、怎么表现得、进程空间地址、物理地址、虚拟地址、为什么存在进程空间地址、如何感性得去理解进程空间地址、环境变量是如何使用的。 目录 1. 冯诺伊曼体系结构 1.1 是什么 1.2 结论 …...