Apache HttpClient超时的原因及解决方案
小明 Lv6

几种超时情况分析

背景

超时错误通常发生在使用Apache HttpClient库进行HTTP请求的时候,它表示连接管理器无法为请求提供一个可用的连接。这个错误可能是由以下原因引起的:

  • 服务器响应时间过慢,导致连接管理器占用了大量的请求线程而没有得到释放。
  • 连接池设置不合理,例如连接数过少或者连接超时时间设置太短等。
  • 网络问题,例如DNS解析失败、网络异常等。

如果遇到这个问题,可以尝试以下几种解决方案:

  1. 调整连接池的配置,将最大连接数、每个路由的最大连接数以及连接空闲超时时间等参数调整为合适的值。
  2. 增加请求超时时间,使得系统能够有更多的时间等待连接管理器为请求分配连接。
  3. 检查网络环境,确保网络正常运行,并且DNS能够正常解析地址。
  4. 在复杂的系统中,使用异步非阻塞的HTTP客户端,能够有效地避免此类问题的出现。

Connection lease request time out

根据实际情况,调整httpClient连接池的配置,具体有如下参数:
ConnectTimeout:连接建立时间,即三次握手完成时间(单位是ms),超时则抛出ConnectionTimeOutException
SocketTimeout:连接建立后,数据传输过程中数据包之间间隔的最大时间(单位是ms),超时则抛出SocketTimeOutException
ConnectionRequestTimeouthttpclient使用连接池来管理连接,这个时间就是从连接池获取连接的超时时间(单位是ms),超时则抛出ConnectionPoolTimeoutException
maxConnTotal:是同时间正在使用的最多的连接数
maxConnPerRoute是针对一个域名同时间正在使用的最多的连接数
因此,如果是需要频繁调用同一个域名,那么即使maxConnTotal设置再大,还是受限制于maxConnPerRoute

配置举例

1
2
3
4
5
6
7
8
9
10
11
12
13
private static HttpClient client;

static {
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(5000)
.setConnectionRequestTimeout(1000)
.setSocketTimeout(5000).build();
client = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig)
.setMaxConnTotal(200)
.setMaxConnPerRoute(50)
.build();
}

解决办法

根据报错提示,追溯源码,该报错是因为从连接池获取连接时,当前时间大于我们设置获取连接池的时间1秒,所以就抛出异常。所以,我们将连接池的连接数调大,同时适当调大连接池连接时间,即可解决问题。

关注获取更多资源

image
 评论