Java 如何诊断泄漏的http连接(org.apache.http.impl.conn.tsccm.connpolbyroute)

Java 如何诊断泄漏的http连接(org.apache.http.impl.conn.tsccm.connpolbyroute),java,amazon-web-services,connection-pooling,apache-httpclient-4.x,Java,Amazon Web Services,Connection Pooling,Apache Httpclient 4.x,我有一个在Amazon的EC2上运行的多线程java程序。它使用org.apache.http.impl.client.DefaultHttpClient,通过HttpPost和HttpGet从供应商处查询和获取数据项。同时,它使用AWS的JavaSDK将检索到的数据项推送到S3中 运行几天后,我出现了通常伴随http连接泄漏而来的症状: org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connec

我有一个在Amazon的EC2上运行的多线程java程序。它使用org.apache.http.impl.client.DefaultHttpClient,通过HttpPost和HttpGet从供应商处查询和获取数据项。同时,它使用AWS的JavaSDK将检索到的数据项推送到S3中

运行几天后,我出现了通常伴随http连接泄漏而来的症状:

org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection
at org.apache.http.impl.conn.tsccm.ConnPoolByRoute.getEntryBlocking(ConnPoolByRoute.java:417)
at org.apache.http.impl.conn.tsccm.ConnPoolByRoute$1.getPoolEntry(ConnPoolByRoute.java:300)
at org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager$1.getConnection(ThreadSafeClientConnManager.java:224)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:391)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:820)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:754)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:732)
因为AWS和我对数据供应商的请求都使用Http连接,所以我不太确定我到底忘记了在哪里使用
HttpEntity.consume()
,或者
S3ObjectInputStream.close()
(除非它是其他东西…)


所以我的问题是:有没有办法监控
org.apache.http.impl.conn.tsccm.ConnPoolByRoute
,这样至少我可以在我开始泄漏连接/未正确使用的实体/未关闭的http流时检测到?(我感觉只有在某些情况下才会发生这种情况,例如,当抛出某些异常时,通过传递代码中使用HttpEntities、关闭流等的逻辑)任何关于如何诊断最终导致所有http连接因ConnectionPoolTimeoutException而失败的想法都是非常受欢迎的。我不想在修复问题根本原因的两次尝试之间等待4天以上。

如果您可以访问
org.apache.http.impl.conn.tsccm.ConnPoolByRoute
,然后将其connTTL设置为足够低的值,这样它的
WaitingThreadAborter
最终将终止连接。它将显示一个很好的堆栈跟踪那里。另一个选项是使用CGLIB或其他字节码操作框架创建一个代理类包装
org.apache.http.impl.conn.tsccm.ConnPoolByRoute
。根据您的环境,设置它可能不是那么容易,但它是调试类似您的问题的非常有价值的工具。(是的,如果您碰巧使用spring或纯Aspects,安装将非常简单:)

如果您使用的是
PoolgClientConnectionManager
注意,有方法
getTotalStats()
getStats(最终HttpRoute路由)
它将为您提供一个PoolStats对象,其中包含您要监视的数据

只需从httpclient获取ConnectionManager:

PoolingClientConnectionManager poolManager = (PoolingClientConnectionManager) httpClient.getConnectionManager();

太好了,谢谢你的提示!顺便说一句,我最终发现了我的问题(异常导致我提前返回)。我通过设置org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager=DEBUG进行调试,并通过perl一行程序计算每个线程的
Get Connection
vs
Released Connection
。我看到有一些发布的连接在这里和那里丢失,并在那之前搜索异常。现在看起来很紧张(计数现在匹配了)。多亏了这篇优秀的文章。