一、背景
近期与其他系统进行接口对接,在压测的时候,发现HttpClient会报ConnectionPoolTimeoutException: Timeout waiting for connection from pool异常,特此进行记录。
并发数:20
调用总量:500
接口平均响应时间:2秒以上
二、问题介绍
在测试环境进行压测,会有大量的ConnectionPoolTimeoutException: Timeout waiting for connection from pool异常。
org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.leaseConnection(PoolingHttpClientConnectionManager.java:286)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager$1.get(PoolingHttpClientConnectionManager.java:263)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:190)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:117)
三、问题原因
经过排查,发现原因应用没有显示地设置 maxPerRoute,所以取了默认值,默认值比较小,maxPerRoute 为2, 而maxToal设置的数量为20, 当并发获取连接时,连接不够用,导致了获取连接的线程一直在等待,等待时间为我们创建 HttpClien 实例时自定义的时间,等待时间过长,导致了从连接池中获取连接超时。
四、解决办法
当我将maxPerRoute设置为50后,异常就没有出现了。因此,使用HttpClient的连接池功能时,需要配置合理的最大连接数maxPerRoute、maxTotal。