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

Apache HttpAsyncClient带请求体重试策略测试失败问题咨询

问题根因

Apache HttpAsyncClient 5.x 内置的DefaultHttpRequestRetryStrategy默认有两个限制导致带Body的请求无法重试:

  • 默认仅对被标记为幂等的请求(无请求体的GET/HEAD等请求默认被判定为幂等)执行重试,带请求体的PUT/POST等请求默认不会被判定为可重试请求,避免非幂等请求重复提交产生数据副作用
  • 即使是幂等的PUT请求,只要携带请求体,默认会额外校验请求体是否支持重复读取,虽然SimpleHttpRequest的请求体存储在内存中天然支持重复读取,但默认策略没有开启带缓冲请求体请求的重试开关
解决方案

提供两种可选方案,任选其一即可:

方案1:显式标记请求为幂等

构造请求时添加属性,告知客户端当前请求是幂等的可安全重试:

import org.apache.hc.client5.http.protocol.HttpClientContext

val request: SimpleHttpRequest = SimpleRequestBuilder
  .put(baseUrl)
  .setPath("/test")
  .setBody("{}", ContentType.APPLICATION_JSON)
  // 显式标记请求为幂等,允许重试
  .setAttribute(HttpClientContext.REQUEST_ATTR_IDEMPOTENT, java.lang.Boolean.TRUE)
  .build()

方案2:自定义重试策略,放开校验限制

自定义重试策略类,覆盖默认的重试校验逻辑,按需放开限制:

import org.apache.hc.client5.http.impl.DefaultHttpRequestRetryStrategy
import org.apache.hc.core5.http.{HttpRequest, HttpResponse, HttpStatus}
import org.apache.hc.core5.http.protocol.HttpContext
import org.apache.hc.core5.util.TimeValue
import java.io.IOException

class CustomHttpRequestRetryStrategy(
  maxRetries: Int,
  retryInterval: TimeValue
) extends DefaultHttpRequestRetryStrategy(maxRetries, retryInterval) {

  // 异常场景重试逻辑
  override def retryRequest(
    request: HttpRequest,
    exception: IOException,
    execCount: Int,
    context: HttpContext
  ): Boolean = {
    // 重试次数未超限就允许重试
    execCount <= getMaxRetries
  }

  // 响应状态码异常重试逻辑
  override def retryRequest(
    response: HttpResponse,
    execCount: Int,
    context: HttpContext
  ): Boolean = {
    val statusCode = response.getCode
    // 显式指定429为可重试状态码,可按需扩展其他状态码
    if (statusCode == HttpStatus.SC_TOO_MANY_REQUESTS && execCount <= getMaxRetries) {
      return true
    }
    super.retryRequest(response, execCount, context)
  }
}

创建客户端时使用自定义的重试策略即可:

val httpClient: CloseableHttpAsyncClient = HttpAsyncClients.custom()
  .setRetryStrategy(new CustomHttpRequestRetryStrategy(4, TimeValue.ofMilliseconds(500)))
  .build()

两种方案修改后重新执行测试,带Body的请求也会触发预期的4次重试,Mock服务端会累计收到5次请求。


内容的提问来源于stack exchange,提问作者Gilberto T.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 06:06:03