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
相关产品推荐
相关产品推荐

