ConnectionPoolTimeoutException: Timeout waiting for connection from pool

摘要:
=null){try{inputStream.close();}catch{logger.error;}}}思考httpclient连接池原理是什么样的呢?连接池中主要有三个属性,用于不同状态的连接//存放正在使用的连接privatefinalSetleased;//存放可用的连接privatefinalLinkedListavailable;//存放pending的连接privatefinalLinkedList˂PoolEntryFuture˃pending;默认连接池的大小是多少?我们查看官方代码,发现其默认总大小为20,每个route的默认最大为2publicPoolingHttpClientConnectionManager{super();this.configData=newConfigData();this.pool=newCPool;this.pool.setValidateAfterInactivity;this.connectionOperator=Args.notNull;this.isShutDown=newAtomicBoolean;}close的原理是怎样呢?内部调用的是release()httpClient.close():这种是关闭连接池,将池中的所有资源释放,即真正关闭连接

背景

今天在通过监控系统发现一个错误,错误如下

org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool
	at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.leaseConnection(PoolingHttpClientConnectionManager.java:316)
	at org.apache.http.impl.conn.PoolingHttpClientConnectionManager$1.get(PoolingHttpClientConnectionManager.java:282)
	at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:190)
	at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186)
	at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
	at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
	at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56)

动作

  1. 起初怀疑是连接池设置过小,故查看代码对连接池大小的设置

连接池大小

  1. 发现连接池设置已经足够大,我们的业务完全用不到这么多的连接数,故怀疑连接用完没有被释放。查看服务器上连接数
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

连接状态及数量

查看代码, 发现确实没有释放连接,如下

HttpResponse response = httpclient.execute(httpPost);

List<String> lines = IOUtils.readLines(response.getEntity().getContent(), "utf-8");
StringBuffer res = new StringBuffer();
for (String line : lines) {
   res.append(line);
}
       
ChatMessage chatMessage = getChatMessage(sendChatMessageDTO, replyMessageInfo, sendMessageesResultBO);
return chatMessage;

解决

即然发现了问题,我们把连接用完归还到连接池即可。

HttpPost httpPost = new HttpPost(connectUrl);
InputStream inputStream = null;
try {
            
    HttpResponse response = httpclient.execute(httpPost);
    inputStream = response.getEntity().getContent();
    List<String> lines = IOUtils.readLines(inputStream, "utf-8");
} catch (Exception e){
    logger.error("connect error", e);
    if(httpPost != null){
    	httpPost.abort();
     }
} finally {
    if(inputStream != null){
        try {
            inputStream.close();
         } catch (Exception e){
            logger.error("", e);
         }
    }
}

思考(基于版本4.5)

  • httpclient 连接池原理是什么样的呢?

连接池中主要有三个属性,用于不同状态的连接

//存放正在使用的连接
private final Set<E> leased;
//存放可用的连接
private final LinkedList<E> available;
//存放 pending 的连接 
private final LinkedList<PoolEntryFuture<E>> pending;
  • 默认连接池的大小是多少?

我们查看官方代码(版本4.5), 发现其默认总大小为20,每个 route 的默认最大为 2

 public PoolingHttpClientConnectionManager(
        final HttpClientConnectionOperator httpClientConnectionOperator,
        final HttpConnectionFactory<HttpRoute, ManagedHttpClientConnection> connFactory,
        final long timeToLive, final TimeUnit timeUnit) {
        super();
        this.configData = new ConfigData();
        this.pool = new CPool(new InternalConnectionFactory(
                this.configData, connFactory), 2, 20, timeToLive, timeUnit);
        this.pool.setValidateAfterInactivity(2000);
        this.connectionOperator = Args.notNull(httpClientConnectionOperator, "HttpClientConnectionOperator");
        this.isShutDown = new AtomicBoolean(false);
    }
  • close 的原理是怎样呢?

有两种 close

  1. CloseableHttpResponse.close(): 这种方式是将用完的连接放回连接池的可用集合,并不是将连接真正关闭。内部调用的是 release()
  2. httpClient.close(): 这种是关闭连接池,将池中的所有资源释放,即真正关闭连接

免责声明:文章转载自《ConnectionPoolTimeoutException: Timeout waiting for connection from pool》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇OCR库Tesseract初探python【第五篇】常用模块学习下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

Android开发实战——记账本(4)

父母亲mCostBeanList.remove(位置);builder.setNegativeButton(“取消”;builder.create().show();returntrue;}returnsuper.onOptionsItemSelected(项);...

Oracle 12c新特性(For DBA)

2: Oracle12cIn-MemoryOracle12cIn-Memory提供了一种独特的双格式体系结构,它可以使用传统的行格式和新的内存列格式同时在内存中存储表。与其他NOSQL分片结构相比,OracleSharding提供了优异的运行时性能和更简单的生命周期管理。OracleSharding使用GDS体系结构自动部署和管理分片和复制技术。GDS还提供...

Fiddler抓包7-post请求(json)(转载)

2.查看上图中的红色框:这里只支持application/x-www-form-urlencoded格式的body参数,即json格式。您需要检查JOSN列中的five和xml。1.如果遇到text/xml格式的正文,如下图所示...

C# 没落了吗?

首先,这个数字--------------------------------------------C#是否正在衰落与微软的整个平台密切相关。近年来,使用C#的人越来越少,这也是因为越来越少的人专门为Microsoft平台开发产品。现在是移动时代,微软基本上错过了互联网和移动互联网这两波浪潮。现在生活不容易。在软件工程中,人们常说“唯一不变的就是改变本身”...

Linux 安装.src.rpm源码包的方法

接下来是rpm安装过程。...