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

如何使用Spring @Retryable为指定HTTP错误状态码的外部API调用重试

Spring @Retryable 针对指定5xx HTTP状态码重试实现方案

核心逻辑

@Retryable 注解默认基于异常类型触发重试,要实现按指定HTTP状态码重试,仅需从API调用抛出的异常中提取响应状态码,匹配你需要的500/502/503/504四类状态码即可。

方案1:SpEL表达式实现(最简方案)

直接使用@Retryable提供的exceptionExpression属性编写判断逻辑,无需新增自定义类,适配不同的HTTP客户端配置如下:

适配RestTemplate

Spring RestTemplate默认会将5xx响应封装为HttpServerErrorException,注解配置如下:

@Service
public class MyService {

  @Retryable(
      maxAttempts = 3,
      exceptionExpression = """
          #root instanceof T(org.springframework.web.client.HttpServerErrorException) && 
          {500,502,503,504}.contains(#root.getStatusCode().value())
          """,
      backoff = @Backoff(delay = 100, multiplier = 2)
  )
  public List<String> doCallExternalResource() {
     // 外部API调用逻辑,例如RestTemplate.exchange(...)
  }
}

适配OpenFeign

OpenFeign调用产生的异常为FeignException,只需修改表达式中的异常类型和状态码获取方式:

@Retryable(
    maxAttempts = 3,
    exceptionExpression = "#root instanceof T(feign.FeignException) && {500,502,503,504}.contains(#root.status())",
    backoff = @Backoff(delay = 100, multiplier = 2)
)

方案2:自定义重试策略(适合复杂判断场景)

如果后续需要扩展更复杂的重试规则,可以自定义重试策略实现:

  1. 编写自定义重试策略类
public class Custom5xxRetryPolicy extends SimpleRetryPolicy {
    // 需要重试的状态码列表
    private static final List<Integer> RETRY_STATUS_CODES = List.of(500, 502, 503, 504);

    @Override
    public boolean canRetry(RetryContext context) {
        Throwable lastError = context.getLastThrowable();
        // 仅匹配指定异常和状态码
        if (lastError instanceof HttpServerErrorException serverError) {
            return RETRY_STATUS_CODES.contains(serverError.getStatusCode().value())
                    && super.canRetry(context);
        }
        // 其他异常不重试
        return false;
    }
}
  1. 注册自定义RetryTemplate
@Configuration
public class RetryConfig {
    @Bean
    public RetryTemplate custom5xxRetryTemplate() {
        RetryTemplate retryTemplate = new RetryTemplate();
        // 绑定自定义重试策略
        retryTemplate.setRetryPolicy(new Custom5xxRetryPolicy());
        // 配置退避策略
        ExponentialBackOffPolicy backOffPolicy = new ExponentialBackOffPolicy();
        backOffPolicy.setInitialInterval(100);
        backOffPolicy.setMultiplier(2);
        retryTemplate.setBackOffPolicy(backOffPolicy);
        return retryTemplate;
    }
}
  1. 业务方法绑定自定义RetryTemplate
@Service
public class MyService {
  @Retryable(retryTemplate = "custom5xxRetryTemplate")
  public List<String> doCallExternalResource() {
     // 外部API调用逻辑
  }
}

注意事项

  • 必须在启动类或配置类上添加@EnableRetry注解,否则@Retryable不会生效
  • 被@Retryable注解的方法不能被同一个类的其他方法内部调用,否则AOP切面不生效

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 07:15:07