You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Retry重复请求及CircuitBreaker配置后重试异常问题咨询

问题根因
  • 重试逻辑嵌套叠加:你当前用了两层重试相关注解,外层Status类的getStatus方法加了@Retryable,内层StatusClient的方法加了Spring Retry提供的@CircuitBreaker,而Spring Retry的@CircuitBreaker本身内置了重试逻辑,两层重试规则叠加导致触发了预期外的重复调用。
  • 异常触发逻辑未做限制:你没有为重试注解指定触发异常的范围,所有向上抛出的异常(包括服务端返回错误、响应体反序列化异常、甚至内部运行时异常)都会触发重试。你第一次观测到的两次成功请求,大概率是第一次请求已经成功拿到远端响应,但后续反序列化或者处理过程中抛出了瞬态异常,触发重试后第二次调用完全成功,因此打印了两次成功日志。
  • 配置参数含义混淆:@CircuitBreaker的maxAttempts参数指的是断路器打开前允许的连续失败次数,而非重试次数。你将该参数改为1后,第一次调用远端返回503触发异常,断路器直接打开,后续外层@Retryable的剩余2次重试请求会被断路器直接拦截,抛出ExhaustedRetryException,不会发起实际远端调用,刚好匹配你配置的retry.maxAttempts=3的总尝试次数。
解决方法
  • 移除重复重试逻辑:二选一重试方案即可,不需要嵌套注解:
    1. 保留@CircuitBreaker,删除外层的@Retryable注解,直接在@CircuitBreaker中配置重试和熔断规则即可覆盖需求
    2. 若要单独用@Retryable控制重试,可将@CircuitBreaker的maxAttempts设为1,关闭其内置重试能力,仅保留熔断功能
  • 明确重试触发范围:给重试注解增加include属性,仅对需要重试的异常(如网络异常、远端返回5xx错误抛出的RemoteClientException等)触发重试,避免无差别重试:
    @Retryable(include = {RemoteClientException.class, java.io.IOException.class}, 
               maxAttemptsExpression = "#{${remote.retry.maxAttempts}}", 
               backoff = @Backoff(delayExpression = "#{${remote.retry.delay}}"))
    
  • 补充排查日志:在方法入口增加调用次数日志,同时捕获完整异常栈打印,确认每次重试触发的具体原因,避免隐性异常导致的误重试。

内容的提问来源于stack exchange,提问作者Chandresh Mishra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 23:06:07