如何监视/记录 Tomcat 的线程池?

Posted

技术标签:

【中文标题】如何监视/记录 Tomcat 的线程池?【英文标题】:How can I monitor/log Tomcat's thread pool? 【发布时间】:2011-11-12 02:54:42 【问题描述】:

我有一个 Tomcat 安装,我怀疑由于线程未正确释放,线程池可能会随着时间的推移而减少。当达到 maxthreads 时,我在 catalina.out 中收到一个错误,但我想每五分钟将正在使用的线程数记录到一个文件中,以便我可以验证这个假设。有人可以建议如何做到这一点吗?

此外,在此安装中没有 Tomcat 管理器,似乎执行原始安装的人出于某种原因删除了管理器 webapp。我不确定经理是否能够执行上述操作,或者我是否可以在不损坏现有安装的情况下重新安装它?我真正想做的就是跟踪线程池。

另外,我注意到 Tomcat 的最大线程数为 200,但 Apache 的最大并发连接数较低(Apache 使用 mod_proxy 和 mod_proxy_ajp (AJP 1.3) 来支持 Tomcat)。这似乎也有问题,这些数字之间的正确关系是什么?

非常感谢任何帮助:D

更新:只是一个快速更新,说明直接 JMX 访问有效。但是我还必须设置 Dcom.sun.management.jmxremote.host。我将它设置为 localhost 并且它可以工作,但是没有它就没有骰子。如果其他人在尝试启用 JMX 时遇到类似问题,我建议您也设置此值,即使您是从本地计算机连接。似乎某些版本的 Tomcat 需要它。


只是一个快速更新,说明直接 JMX 访问有效。但是我还必须设置 Dcom.sun.management.jmxremote.host。我将它设置为 localhost 并且它可以工作,但是没有它就没有骰子。如果其他人在尝试启用 JMX 时遇到类似问题,我建议您也设置此值,即使您是从本地计算机连接。似乎某些版本的 Tomcat 需要它。

【问题讨论】:

如果您在 Java 5+ 上运行,您也许可以使用 jconsole 监控 JVM 线程池。 我尝试使用 jconsole 连接到 Tomcat,但它失败了(这是尝试使用本地主机上的 Tomcat 的 PID 进行连接,而不是远程连接)。是否需要启用 JMX 才能使用 jconsole? AFAIK,在 Java 5 中您需要启用 JMX。从 Java 6 开始,这对于本地访问应该是不必要的。或者,有一个 Hotspot JVM 选项,它从命令行创建一个线程转储(IIRC 它是-XX:+HeapDumpOnCrtlBreak,它将创建一个堆转储和一个线程转储) 你能显示tomcat给出的错误信息吗? tomcat的最大线程设置是指它可以使用的连接器数量,本质上是它可以处理的并发连接数......所以你提到的两个数字应该是相似的。至少这是我的理解 错误很严重:所有线程(200)当前都在忙,正在等待。增加最大线程数或检查 servlet 状态。同样,当这种情况发生时,Tomcat 会停止服务页面并给出 503。我认为这两个数字应该相似,即 Apache 中的 MaxClients 是最大同时连接数,所以这不应该也是 200? 【参考方案1】:

直接 JMX 访问

尝试将此添加到catalina.sh/bat

-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=5005
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false

更新:Alex P 建议在某些情况下可能还需要以下设置:

-Dcom.sun.management.jmxremote.host=localhost

这可以在端口 5005 上启用远程匿名 JMX 连接。您也可以考虑使用 JVisualVM,它更受欢迎,允许通过插件浏览 JMX。

您正在寻找的是Catalina -> ThreadPool -> http-bio-8080 -> 各种有趣的指标。

JMX 代理 servlet

更简单的方法可能是在http://localhost:8080/manager/jmxproxy 下使用Tomcat 的JMX proxy servlet。例如试试这个查询:

$ curl --user tomcat:tomcat http://localhost:8080/manager/jmxproxy?qry=Catalina:name=%22http-bio-8080%22,type=ThreadPool

一点点grepping 和脚本,您就可以轻松地远程监控您的应用程序。注意tomcat:tomcatconf/tomcat-users.xml 中具有manager-jmx 角色的用户的用户名/密码。

【讨论】:

谢谢 Tomasz,我会试一试的。我不认为我可以使用代理 servlet,因为它在管理器下,不幸的是,由于某种原因,它似乎已从安装中删除 - 管理目录存在,但管理器不存在。 我尝试使用上面的 curl/jmxproxy,但它只给出了 404,所以我认为经理很无聊,我将尝试按照上面的建议在显式端口上启用 JMX,看看是否有效。感谢大家的帮助!【参考方案2】:

您可以部署jolokia.war,然后以 JSON 格式检索 mbeans 值(无需管理器):

http://localhost:8080/jolokia/read/Catalina:name=*,type=ThreadPool?ignoreErrors=true

如果你只想要一些值(currentThreadsBusy、maxThreads、currentThreadCount、connectionCount):

http://localhost:8080/jolokia/read/Catalina:name=*,type=ThreadPool/currentThreadsBusy,maxThreads,currentThreadCount,connectionCount?ignoreErrors=true


    request: 
       mbean: "Catalina:name="http-nio-8080",type=ThreadPool",
       attribute: [
          "currentThreadsBusy",
          "maxThreads",
          "currentThreadCount",
          "connectionCount"
       ],
       type: "read"
    ,
    value: 
       currentThreadsBusy: 1,
       connectionCount: 4,
       currentThreadCount: 10,
       maxThreads: 200
    ,
    timestamp: 1490396960,
    status: 200

注意:此示例适用于 Tomcat7 +。

【讨论】:

您可以通过使用通配符来避免引用http-nio-8080或http-bio-8080,这将带来所有线程池:curl -XGET 'http://localhost:8080/jolokia/read/Catalina:name=*,type=ThreadPool?ignoreErrors=true'【参考方案3】:

更多的企业解决方案。我一直在我们的生产环境中使用 New Relic。

这提供了线程池随时间变化的图表。

【讨论】:

很棒的工具。太糟糕了,定价太疯狂了

以上是关于如何监视/记录 Tomcat 的线程池?的主要内容,如果未能解决你的问题,请参考以下文章

如何计算tomcat线程池大小?

如何增加tomcat线程池中的线程数?

tomcat线程池详解

17 | Executor组件:Tomcat如何扩展Java线程池?

Tomcat是如何修正JDK原生线程池bug的?

JDK线程池Tomcat线程池Dubbo线程池的不同