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

Spring新RestClient遇429自动重试,如何配置重试逻辑?

Spring Boot 3.2.1 RestClient 429状态码自动重试问题

我使用Spring Boot 3.2.1版本的RestClient,代码如下:

val restClient = RestClient.builder()
    .defaultHeader(HttpHeaders.CONTENT_TYPE, APPLICATION_JSON.toString())
    .baseUrl(simproWebhookContext.inboundWebhookUrl!!)
    .build()

restClient.post()
    .contentType(APPLICATION_JSON)
    .body(deriveSimproContactJsonBody(custContact, siteContact, simproWebhookContext))
    .retrieve()
    .toBodilessEntity()

在单元测试中:

  • 当Mock返回400状态码时,请求次数为1次,符合预期:
    wm1.stubFor(post(urlEqualTo("/test-inboundWebhookUrl"))
        .willReturn(aResponse().withStatus(400)))
    
    val requests = findAll(postRequestedFor(urlEqualTo("/test-inboundWebhookUrl")))
    assertEquals(requests.size, 1)
    
  • 但当Mock返回429状态码时,请求次数总是2次:
    wm1.stubFor(post(urlEqualTo("/test-inboundWebhookUrl"))
    .willReturn(aResponse().withStatus(429)))
    

我代码里没加任何429状态的处理逻辑,推测这是RestClient的默认特性,请问该如何配置它的重试逻辑?


解决方案

Spring Boot 3.2.x版本的RestClient默认集成了重试机制,针对429 Too Many Requests这类限流状态码会自动触发1次重试。要自定义或关闭该行为,可通过以下方式配置:

1. 完全关闭默认重试

构建RestClient时,指定不带重试逻辑的ClientHttpRequestFactory,比如SimpleClientHttpRequestFactory:

val restClient = RestClient.builder()
    .defaultHeader(HttpHeaders.CONTENT_TYPE, APPLICATION_JSON.toString())
    .baseUrl(simproWebhookContext.inboundWebhookUrl!!)
    .requestFactory(SimpleClientHttpRequestFactory()) // 禁用默认重试
    .build()

2. 自定义重试策略

如果需要灵活控制重试规则(如指定重试状态码、次数、间隔),可结合RetryTemplate和ClientHttpRequestInterceptor实现:

步骤1:定义重试规则

val retryTemplate = RetryTemplate().apply {
    // 设置可重试的状态码和最大重试次数
    setRetryPolicy(SimpleRetryPolicy().apply {
        val retryableStatuses = mapOf(
            HttpStatus.TOO_MANY_REQUESTS.value() to true,
            HttpStatus.INTERNAL_SERVER_ERROR.value() to true
        )
        setRetryableStatusCodeSet(retryableStatuses.keys)
        setMaxAttempts(3) // 含首次请求,共3次尝试
    })
    // 设置重试间隔(固定1秒)
    setBackOffPolicy(FixedBackOffPolicy().apply {
        setBackOffPeriod(1000)
    })
}

步骤2:添加重试拦截器

val restClient = RestClient.builder()
    .defaultHeader(HttpHeaders.CONTENT_TYPE, APPLICATION_JSON.toString())
    .baseUrl(simproWebhookContext.inboundWebhookUrl!!)
    .requestInterceptor { request, body, execution ->
        retryTemplate.execute {
            execution.execute(request, body)
        }
    }
    .build()

3. 全局配置调整

若要统一配置所有RestClient的重试行为,可在application.yml中添加全局属性:

spring:
  restclient:
    retry:
      enabled: false # 全局禁用重试
      max-attempts: 3 # 全局最大重试次数(含首次请求)
      back-off:
        initial-interval: 1000 # 初始重试间隔(毫秒)

注意:RestClientBuilder的自定义配置会覆盖全局配置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 02:33:31