【每日鲜蘑】异常`org.apache.http.NoHttpResponseException`解决

7,049 阅读1分钟

这是HTTP引起的异常,属于偶然发生异常。

异常日志

org.apache.http.NoHttpResponseException: The target server failed to respond

解决方案

服务端方案

客户端可以检测到服务已经过期了,主动关闭。

  • 追踪代码我们可以看到是 client 是从 HttpHeader 中读取 Keep-Alive: timeout=xx,如果没有读到就认为永不超时。
  • 而 Nginx 配置的第二个参数就是这个,因此只要服务端将 keepalive_timeout 30s;改为 keepalive_timeout 30s 29s;即可,这里少 1s 为了防止网络延时造成的并发问题。

客户端方案

如果服务端不方便修改,那么第二方案是客户端这边修改,比较麻烦。

  • 首先保证用最新的 httpClient
  • 其次有三种方法:
    1. 对于 jest 这类有定时 closeIdleConnection 的,可以将调度时间调整为 keep alive 时间的一半以下以保证超时前回收
    2. 根据 keep Alive 时间,调整 validateAfterInactivity 小于keepAlive Time`,但这种方法依旧不能避免同时关闭。
    3. 补偿方案,使用Retry重新发送尝试一次。HttpClient 默认是打开自动重试的,不要调用 disableAutomaticRetries 即可

推荐的方案

  1. 客户端使用短连接,比如换成 UrlConnection
  2. HttpClient 连接保活时间调的小于 15s 或者将 nginxkeepalive_timeout 调的大于 30s;
  3. 不用 PoolingHttpClientConnectionManager
  4. 出错后重试,HttpClientRetryHandler
  5. JDK11已经带了 HttpClinet,这不吸引人么?