【问题标题】:High tomcat thread count caused by threads waiting on MultiThreadedHttpConnectionManager ConnectionPool线程在 MultiThreadedHttpConnectionManager ConnectionPool 上等待导致的 tomcat 线程计数高
【发布时间】:2011-09-23 18:08:14
【问题描述】:

我们最近开始看到我们的 tomcat 服务器上的线程数出现峰值(峰值超过 1000,而通常在 100 左右)。我们在其中一个 tomcat 服务器上执行了线程转储,而它的线程数很高,发现有大量线程在 MultiThreadedHttpConnectionManager$ConnectionPool 上等待,堆栈跟踪如下:

“TP-Processor21700”守护进程prio=10 tid=0x4a0b3400 nid=0x2091 in Object.wait() [0x399f3000..0x399f4004] java.lang.Thread.State:等待(在对象监视器上) 在 java.lang.Object.wait(本机方法) - 等待 (一个 org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$ConnectionPool) 在 org.apache.commons.httpclient.MultiThreadedHttpConnectionManager.doGetConnection(MultiThreadedHttpConnectionManager.java:518) - 锁定 (一个 org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$ConnectionPool) 在 org.apache.commons.httpclient.MultiThreadedHttpConnectionManager.getConnectionWithTimeout(MultiThreadedHttpConnectionManager.java:416) 在 org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:153) 在 org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397) 在 org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323) ...

在我们的代码中有 3 个点调用了 httpClient.executeMethod()(通过对另一个 tomcat 服务器的 http 请求获取信息)。在每种情况下,传递给它的 GetMethod 对象都事先设置了其套接字超时值(即通过 getMethod.getParams().setSoTimeout();),并且 MultiThreadedConnectionManager 在 spring 中配置为具有 10 秒的 connectionTimeout 值。我注意到的一件事是 3 个 httpClient.executeMethod() 调用中只有 2 个调用了对 getMethod.releaseConnection() 的调用,所以我想知道这是否可能是问题的原因(即连接未明确发布)。然而奇怪的是 这个问题在最近几天才开始出现,并且源代码已经一年多没有修改了,而且最近通过 tomcat 服务器的请求没有激增。在问题开始发生前几天确实发生的一项更改是我们将 tomcat 服务器使用的 JVM 从 Java 5(1.5 更新 14)升级到 Java 6(1.6 更新 25)。我们已尝试将 JVM 版本暂时恢复为 Java 5,以查看问题是否停止发生,但问题并未停止。还有一点需要注意的是,在大多数情况下,tomcat 服务器最终会恢复并且 线程数恢复正常 - 我们只有一个实例,其中一个 tomcat 进程似乎由于线程数增加而崩溃。

我们正在运行 Tomcat 5.5,并在 Red Hat linux 环境中针对 Java 1.6 更新 25 运行 commons-httpclient-3.1.jar。

如果您能就导致此问题的原因提出任何建议,请告诉我。

谢谢。

【问题讨论】:

    标签: httpclient


    【解决方案1】:

    问题确实是由于 3 个 httpClient.executeMethod(getMethod) 调用中只有 2 个调用了 getMethod.releaseConnection()。确保所有 3 个 httpClient.executeMethod(getMethod) 调用都在 try/catch 块内,然后是包含对 getMethod.releaseConnection() 调用的 finally 块,以防止发生高线程数。尽管这段代码在我们的实时系统中已经存在了一年多,但似乎最近才开始出现高线程数问题的原因是各种搜索引擎爬虫已经开始使用大量 URL 请求访问该站点,导致代码所在的正在使用连接,但随后未释放执行。问题解决了。

    【讨论】:

      猜你喜欢
      • 2021-10-14
      • 2017-12-25
      • 1970-01-01
      • 2023-03-11
      • 2013-05-17
      • 2016-02-17
      • 1970-01-01
      • 2011-02-04
      • 1970-01-01
      相关资源
      最近更新 更多