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

Apache HttpClient5出现NoHttpResponseException:主机无响应问题求助

RestTemplate + Apache HttpClient5 出现 NoHttpResponseException 分析与解决

异常信息

Caused by: org.apache.hc.core5.http.NoHttpResponseException: <host> failed to respond
    at org.apache.hc.core5.http.impl.io.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:301)
    at org.apache.hc.core5.http.impl.io.HttpRequestExecutor.execute(HttpRequestExecutor.java:175)
    at org.apache.hc.core5.http.impl.io.HttpRequestExecutor.execute(HttpRequestExecutor.java:218)
    at org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager$InternalConnectionEndpoint.execute(PoolingHttpClientConnectionManager.java:712)
    at org.apache.hc.client5.http.impl.classic.InternalExecRuntime.execute(InternalExecRuntime.java:216)
    at org.apache.hc.client5.http.impl.classic.MainClientExec.execute(MainClientExec.java:116)
    at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
    at org.apache.hc.client5.http.impl.classic.ConnectExec.execute(ConnectExec.java:188)
    at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
    at org.apache.hc.client5.http.impl.classic.ProtocolExec.execute(ProtocolExec.java:192)
    at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
    at org.apache.hc.client5.http.impl.classic.HttpRequestRetryExec.execute(HttpRequestRetryExec.java:96)
    at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
    at org.apache.hc.client5.http.impl.classic.ContentCompressionExec.execute(ContentCompressionExec.java:152)
    at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
    at org.apache.hc.client5.http.impl.classic.RedirectExec.execute(RedirectExec.java:115)
    at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
    at org.apache.hc.client5.http.impl.classic.InternalHttpClient.doExecute(InternalHttpClient.java:170)
    at org.apache.hc.client5.http.impl.classic.CloseableHttpClient.execute(CloseableHttpClient.java:106)
    at org.apache.hc.client5.http.impl.classic.CloseableHttpClient.execute(CloseableHttpClient.java:55)
    at org.springframework.http.client.HttpComponentsClientHttpRequest.executeInternal(HttpComponentsClientHttpRequest.java:93)
    at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
    at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:66)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:864)

问题原因

  • 连接池复用无效连接:HttpClient连接池会复用TCP连接,若目标服务器主动断开空闲连接(比如超时回收),但客户端连接池未及时清理,复用该连接发送请求时就会报错。
  • 服务器端过载或超时:目标服务压力过大,无法及时处理请求,直接关闭连接。
  • 网络中间设备断开连接:防火墙、负载均衡器等设备在连接空闲一段时间后主动断开,客户端未感知。
  • 服务器端异常:服务崩溃、重启,导致正在处理的请求被中断。

解决方案

1. 配置连接池的无效连接校验与回收

通过PoolingHttpClientConnectionManager设置空闲连接校验,每次使用连接前自动校验是否有效,同时配置连接存活时间:

PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
// 设置最大总连接数和单路由最大连接数
connectionManager.setMaxTotal(200);
connectionManager.setDefaultMaxPerRoute(20);
// 每次使用连接前,校验空闲超过5秒的连接是否有效
connectionManager.setValidateAfterInactivity(TimeValue.ofSeconds(5));

2. 开启针对该异常的请求重试

配置HttpClient5的重试策略,对NoHttpResponseException这类可重试异常进行自动重试:

HttpRequestRetryStrategy retryStrategy = new DefaultHttpRequestRetryStrategy(
        3, // 最大重试次数
        TimeValue.ofSeconds(1), // 重试间隔时间
        Collections.singleton(NoHttpResponseException.class) // 指定需要重试的异常
);

3. 设置合理的超时时间

配置连接超时、读取超时,避免长时间等待无响应的连接:

RequestConfig requestConfig = RequestConfig.custom()
        .setConnectTimeout(TimeValue.ofSeconds(10)) // 连接超时10秒
        .setResponseTimeout(TimeValue.ofSeconds(15)) // 读取响应超时15秒
        .build();

4. 完整的RestTemplate配置示例

将以上配置整合到RestTemplate的Bean中:

@Bean
public RestTemplate restTemplate() {
    PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
    connectionManager.setMaxTotal(200);
    connectionManager.setDefaultMaxPerRoute(20);
    connectionManager.setValidateAfterInactivity(TimeValue.ofSeconds(5));

    HttpRequestRetryStrategy retryStrategy = new DefaultHttpRequestRetryStrategy(
            3,
            TimeValue.ofSeconds(1),
            Collections.singleton(NoHttpResponseException.class)
    );

    RequestConfig requestConfig = RequestConfig.custom()
            .setConnectTimeout(TimeValue.ofSeconds(10))
            .setResponseTimeout(TimeValue.ofSeconds(15))
            .build();

    CloseableHttpClient httpClient = HttpClients.custom()
            .setConnectionManager(connectionManager)
            .setRetryStrategy(retryStrategy)
            .setDefaultRequestConfig(requestConfig)
            .build();

    HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
    return new RestTemplate(requestFactory);
}

5. 服务器端排查

  • 检查目标服务的日志,确认是否存在过载、崩溃或连接回收策略配置问题。
  • 调整服务器端的连接超时设置,避免主动断开正常连接。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 06:55:15