接口调用总失败?试试Spring官方重试框架Spring-Retry

构建统一AI调用层:基于策略模式与适配器设计的多模型集成方案 在AI应用开发中,API集成是一个常见挑战。不同服务商提供的SDK、认证方式和响应格式各异,导致代码复杂度高、维护困难。通过抽象接口与适配器模式,可以构建统一的调用层,将底层差异封装起来,为上层业务提供一致的编程体验。这种设计不仅提升了代码的可维护性和可扩展性,还能灵活支持多模型路由、成本控制和故障转移等高级功能。在工程实践中,aisuite项目正是基于这一理念,通过策略模式实现智能路由,并结合Spring Boot的自动配置机制,简化了OpenAI、DeepSeek等主流AI服务的集成流程,为开发者提供了 阅读详情

01 引言

在现代分布式系统和微服务架构中,服务间的网络调用变得无比频繁。然而,网络是不可靠的,它可能因为瞬时故障(如网络抖动、服务短暂过载、资源临时不可用等)导致调用失败。简单地一失败就放弃,会严重降低系统的健壮性和用户体验尤其调用第三方接口时表现最明显。

因此,重试机制成为了构建 resilient(弹性)系统不可或缺的一环。Spring Retry 作为 Spring 生态系统中的一员,提供了一种声明式、注解驱动的高效重试解决方案,能让你的代码在应对短暂故障时变得更加健壮和优雅。

02 简介

Spring Retry 的核心思想是 AOP(面向切面编程)。它通过代理(Proxy)机制,在目标方法的外部包裹一层重试逻辑。

当你调用一个被 @Retryable 注解的方法时,实际上是在调用一个由 Spring 生成的代理对象,这个代理对象负责在方法执行失败时,根据你配置的策略进行重试。

03 最佳实践

因为Spring Retry的核心思想是AOP,所以声明式重试需要依赖AOP。

3.1 Maven依赖

Spring Boot项目依赖:

<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项目,则需要如下依赖:

<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
    <version>2.0.5</version> <!-- 请使用最新版本 -->
</dependency>
<!-- Spring AOP 依赖 (Spring Boot项目一般已包含) -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
</dependency>
<!-- 如果你使用@Recover,还需要AspectJ的依赖 -->
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
</dependency>

3.2 启用重试功能

@EnableRetry

在项目的配置类或者主启动类上添加 @EnableRetry 注解,以启用 Spring Retry 的自动代理功能。

@SpringBootApplication
@EnableRetry
public class RetryApplication {

    public static void main(String[] args) {
        SpringApplication.run(RetryApplication.class, args);
    }
}

3.3 方法添加@Retryable

@Retryable是最核心的注解,用于标注哪些方法在发生异常时需要重试。

基本参数说明:

  • value / include: 指定需要重试的异常类型数组。默认为空(重试所有异常)。
  • maxAttempts: 最大重试次数(包括第一次调用)。例如设置为 3,意味着最多会调用 3 次方法(1次初始调用 + 2次重试)。
  • backoff: 设置重试退避策略,通常与 @Backoff 注解联用。
  • recover: 服务降级的方法。

3.4 案例代码

我们通过传递参数status来控制异常,重试参数:

  • retryFor = RuntimeException.class:只针对RuntimeException重试。
  • maxAttempts = 4:包含第一次请求总共请求4次
  • delay = 1000:延迟1s重试
  • multiplier = 2.0:延迟时间的乘数(用于指数退避),步长,延迟序列为:1s, 2s, 4s…
@Service
public class RetryServiceImpl implements RetryService{

    @Override
    @Retryable(retryFor = RuntimeException.class,
                maxAttempts = 4,
                backoff = @Backoff(delay = 1000,
                        multiplier = 2.0
                )
    )
    public String invokeMethod(Integer status) {
        System.out.println("invokeMethod 调用时间:"
                + LocalDateTime.now()
                .format(DateTimeFormatter.ofPattern("yyyy-dd-MM HH:mm:ss")));
        // 模拟异常
        if (status != null) {
            throw new RuntimeException("服务中断了......");
        }
        return "SUCCESS";
    }
}

效果:

3.5 服务降级

如果重试完成之后还是响应失败,那么就可以服务降级,返回指定的数据。

这是需要一个注解@Recover来指定降级的方法。

这里的方法名可以随意取,默认会被@Retryable识别,也可以通过recover参数指定方法。

@Recover方法不被执行的原因:

  • 未加@Recover注解

  • recover参数指定错误

  • @Recover修改的方法参数必须是retryFor的异常以及原方法的参数。

    如:

    @Retryable(retryFor = RuntimeException.class)
    public String test(Integer status) {
        // ...  
    }
    
    @Recover
    public String testRecover(RuntimeException e, Integer status) {
      	// ...
    }
    

04 编程式重试

编程式重试的核心是RetryTemplate,使用更加灵活,不受AOP限制。

@Test
void test() throws Throwable {
    RetryTemplate retryTemplate = RetryTemplate.builder()
            .maxAttempts(4)
            .exponentialBackoff(1000, 2, 10000)
            .retryOn(RuntimeException.class)
            .build();


    String execute = retryTemplate.execute(
            (RetryCallback<String, Throwable>) context -> {
        RetryService retryService = new RetryServiceImpl();
        return retryService.invokeMethod(1);
    }, context -> "服务降级了!");

    System.out.println(execute);
}

效果:

05 小结

Spring Retry 提供了 声明式 和 编程式 两种风格来满足不同场景的需求:

  • 无脑上注解:对于大多数通用的重试场景,使用 @Retryable + @Backoff + @Recover 是最高效、最清晰的选择。
  • 动手写代码:当你需要极致灵活和动态控制时,RetryTemplate 配合各种 RetryPolicy 和 BackOffPolicy 是你的不二之选。

快去试试水吧!

YOLOv13保姆级教程+AKConv模块:可变形卷积+自适应核优化,mAP提升3.23%,召回率&mAP50~95显著提升(论文涨点模块已验证) 本文介绍了一种改进的YOLOv13-AKConv模型,通过引入AKConv模块显著提升了目标检测性能。实验结果表明,优化后的模型(绿色曲线)相比原模型(蓝色曲线)在mAP指标上提升了3.23个点,同时召回率、mAP50-95等指标均有明显提升。作者详细阐述了模型移植过程,包括创建yolov13-AKConv.yaml配置文件,修改tasks.py和modules/init.py文件,以及实现AKConv模块的核心代码。该模块采用可变形卷积思想,通过动态生成采样点位置来增强特征提取能力,并集成了BN和SiLU 阅读详情

相关推荐

永磁同步电机定子槽型设计实战:从梨形槽到矩形槽的NVH优化之路

本文深入探讨了永磁同步电机定子槽型设计在NVH优化中的关键作用,对比了梨形槽与矩形槽的性能差异。通过Ansys Maxwell仿真和实际案例,揭示了矩形槽在提升槽满率、降低电磁噪声方面的优势,并总结了五大设计黄金法则,为电机设计工程师提供了实用指导。

weixin_28740299的博客 494

实现重试只知道Spring Retry?试试Spring Boot 整合 Fast Retry 来实现重试机制

在外面日常开发中,服务之间的调用往往存在延迟和失败的情况。比如之前博主写的一篇【Spring Boot集成 Spring Retry 实现容错重试机制并附源码】短信发送远程服务调用争抢锁网络延迟服务宕机或临时故障等问题。为了提高服务的可靠性,我们可以使用重试机制来处理这些问题,之前我们已经介绍了,今天我们介绍另外一款轻量级的Fast Retry库。Fast Retry是一个轻量级的 Java 重试库,它可以方便地为方法调用添加重试机制。

Micro麦可乐的博客 1万+

博图HMI多语言文本列表一键生成攻略:从Excel模板到TIA Portal的完整流程

本文详细介绍了如何利用Excel模板和TIA Portal API实现博图HMI多语言文本列表的一键生成。通过标准化Excel模板设计、解析TIA Portal的XML结构,并结合C#代码实现自动化导入,大幅提升多语言项目的开发效率。特别适用于需要支持多语言版本的自动化设备HMI界面开发。

weixin_26934905的博客 219

还在手写重试机制?试试Spring-Retry吧

在工作中,我们经常会碰到需要调用远程方法的业务,这时候,如果超时了,或者异常了,我们都会让其重试几次,达到一定的重试次数以后,就返回异常信息,今天我们就来了解下Spring-Retry的用法以及实现原理是怎么样的。

jcc4261的博客 748

AutoCAD 2024 LISP实用技巧:自定义快捷命令与高效绘图工具集

本文详细介绍了如何在AutoCAD 2024中部署和使用LISP脚本,打造高效绘图工具集。通过自定义快捷命令,如WFF(超级文字查找替换)、GQT(图层隔离)和LLTJ(智能长度统计),可大幅简化图层管理、文字编辑和测量统计等重复性操作,显著提升绘图效率。

gan8painter的博客 323

精确时钟同步协议ptp/IEEE-1588v2协议-------(1)简介

ptp, 1588V2, IEEE-1588, 精确时钟同步协议

meihualing的专栏 5361

重试总结 spring retry 注解重试

在Spring Boot中使用Spring Retry Springboot 整合Retry 实现重试机制 spring retry 注解重试 如何优雅的进行重试 支持注解的 java 重试框架 基于spring-retry和guava-retry spring boot / cloud (七) 使用@Retryable来进行重处理 JAVA如何优雅的重试?@Retryable(spring的重试机制) 还在手写重试,不妨试试Spring Retry(二) 自己实现简单重试 int times = 3; M

zhaoyang10的专栏 1445

骑砍2霸主MOD开发(9)-游戏大地图(MapScene)

Settlement类型由town,castle,castle_village,village,hideout五种类型组成,通过对GameEntity中添加tag实现类型的加载.大地图中军团(MobileParty)的移动速度,AI寻路,食物消耗等均和当前MobileParty所处地形有关,地形统一被定义为TerrainType,类型有森林,荒漠等.MapScene.Read("Main_map", ref sceneInitializationData, "") 装载Main_map大地图。

骑砍战团&霸主MOD开发 1624

还在手写重试,不妨试试Spring Retry(二)

theme: scrolls-light ???? 个人主页:@青Cheng序员石头 ???? 粉丝福利:加粉丝群 一对一问题解答,获取免费的丰富简历模板、提高学习资料等,做好新时代的卷卷王! 紧接着上一篇《还在手写重试,不妨试试Spring Retry(一)》,点击前往。 四、RetryTemplate RetryTemplate是使用注解形式重试的一种替代。 4.1 Re...

DynmicResource的博客 2297

YOLOv11知识蒸馏实战:让小模型拥有大模型90%精度,速度提升3倍的终极教程

在self.alpha = alpha # 蒸馏损失权重self.temperature = temperature # 温度系数,控制分布平滑度# 输出分布蒸馏(KL散度损失)# 中间特征蒸馏(MSE损失,对齐中间层特征)# 总蒸馏损失知识蒸馏是YOLOv11在“小模型高性能部署”场景的“破局之法”——它让小模型能“站在大模型的肩膀上”,兼具速度与精度。从损失函数定义到多阶段训练,再到实战落地,本教程已为你铺就了一条清晰的路径。

m0_64661770的博客 803

WQ7033开发指南(应用篇)之2.1 主函数详解(1)

整个系列文章查看: ​​​​​​WQ7033开发指南汇总 目录 1.函数模块位置 2.函数main_chip_init()解析 2.1 cal_data_ana_load() 2.2 函数iot_cache_restore_register()解析 3.函数iot_soc_chip_init()解析 3.1 soc芯片初始化的低功耗使能 3.2 分支预设功能使能 3.3 数据异常中止使能 3.4 外围低速总线访问路径使能 3.5 1.8V DCDC功能配置 3.6 ADC配..

心跳包的博客 804

还在手写重试,不妨试试Spring Retry

对于很多业务,为了使处理更加健壮并减少失败的可能性,有时自动重试失败的操作会有所帮助,使用这种机制它可能使我们的操作在随后的尝试中成功。在本文中,我们将学习如何在 Spring 应用程序中使用 Spring Retry 功能。 一、项目配置 为了启用 Spring Retry 的支持,首先要在pom.xml 文件中添加以下依赖项 <properties> <version.spring.retry>1.3.1</version.spring...

欢迎来到我的博客 214

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

【Spring】SpringRetry重试机制和Spring异步任务发送操作结合应用场景实操,通俗易懂

平时调用一些第三方接口或者内部接口,可能出现处理异常或者超时或者意外因素,我们可以使用重试机制来为用户提高体验。

qq_50446805的博客 761

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

超时重试机制,你真的了解吗?

超时机制和重试机制是解决网络不稳定和服务偶尔抽风的有效手段。超时机制可以避免程序一直卡在那里,重试机制可以提高请求的成功率。💯

qq_56158663的博客 1414

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

软件设计中你考虑过重试了吗?

今天分享一下重试操作,我们知道网络是不可靠的,那么在进行网络请求时,难免会出现请求失败,连接失败等情况,为了保证软件的稳定性和良好的体验,很多时候我们不应该将程序内部出现的问题都抛出给用户,而是应该尽最大可能将软件内部不可抗拒的问题在程序内部处理掉,那么很多时候我们会采取重试操作。

2301_78287784的博客 84

微服务常用技能之优雅的重试

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_33881140的博客 220

springcloud Config客户端连接注册中心开启重试

1.为什么要开启 如果网络波动导致无法连接config注册中心的原因,导致启动直接失败,似乎不是很好。所以,config客户端提供了自动重试的功能。 2。开启之前做的准备 2.1 开启重试功能之前,先确保已经配置了spring.cloud.config.failFast=true。这样做的原因是:希望config客户端可以快速知道当前应用是否能顺利地获取config-server的配置信息。不开启...

qq_43677987的博客 365

Spring Cloud Stream消费失败后的处理策略(四):重新入队(RabbitMQ)

应用场景 之前我们已经通过《Spring Cloud Stream消费失败后的处理策略(一):自动重试》一文介绍了Spring Cloud Stream默认的消息重试功能。本文将介绍RabbitMQ的binder提供的另外一种重试功能:重新入队。 动手试试 准备一个会消费失败的例子,可以直接沿用前文的工程,也可以新建一个,然后创建如下代码的逻辑: @EnableBinding(TestApplication.TestTopic.class)@SpringBootApplicationpublic cla

一个有情怀的程序猿博客 704

电商系统实战:Resilience4J在高并发场景的应用

我们使用Resilience4J的RateLimiter限制每秒最大请求数,根据压测结果设置为1000QPS,超过的请求直接返回"活动太火爆"提示。实际使用中我发现,即使是复杂的微服务架构,在InsCode上也能快速搭建和测试。配置上,我们设置了5秒的超时时间,当错误率超过50%时触发熔断,熔断持续30秒后进入半开状态。同时配置Bulkhead隔离舱模式,为下单服务分配独立的线程池,避免一个服务的崩溃影响整个系统。最终在单机环境下,系统能稳定支撑800QPS的秒杀请求,错误率控制在0.5%以下。

MoonbeamRaven28的博客 921

线上服务频繁超时?用 Resilience4j 打造高可用系统

本文介绍了如何在Spring Boot项目中集成Resilience4j容错库,提升系统稳定性。主要内容包括:Resilience4j的核心功能(熔断、限流、重试、超时)及其与Hystrix的区别;5分钟快速集成指南(添加依赖、配置、注解使用);重点讲解了熔断器的三种状态和实现原理,并提供了详细配置示例和代码实现。文章通过生活化类比帮助理解技术概念,指导开发者通过简单配置为系统添加容错能力,避免服务雪崩。

专注 Java 生态 518
上一篇: 【工具库推荐】Java开发者必备:6款HTTP客户端神器,从经典到未来
下一篇: 一键开启!Spring Boot 的这些「魔法开关」@Enable,你用对了吗?
智_永无止境
博客等级 码龄10年 803粉丝 406原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

智_永无止境

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值