我该如何监控/记录Tomcat的线程池?

33

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

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

此外,我注意到Tomcat的maxthreads为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的线程池。 - Thomas
我尝试使用jconsole连接Tomcat,但失败了(这是尝试使用本地主机上的Tomcat PID进行连接,而不是远程连接)。我需要启用JMX才能使用jconsole吗? - Alex P
据我所知,在Java 5中,您需要启用JMX。从Java 6开始,对于本地访问,这应该是不必要的。或者,有一个Hotspot JVM选项,可以从命令行创建线程转储(如果我没记错的话,它是-XX:+ HeapDumpOnCrtlBreak,它将创建堆转储和线程转储)。 - Thomas
你能展示一下Tomcat正在报的错误信息吗?Tomcat的最大线程设置是指它可以使用的连接器数量,这基本上就是它可以处理的并发连接数...因此,你提到的这两个数字应该是相似的。至少这是我的理解。 - Toby
错误为严重:所有线程(200)都在忙碌中,等待。增加最大线程数或检查servlet状态。当这种情况发生时,Tomcat停止提供页面并显示503。我认为两个数字应该是相似的,即Apache中的MaxClients是最大同时连接数,因此这不应该也是200吗? - Alex P
4个回答

15

直接访问 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

更简单的方法可能是使用Tomcat的JMX代理Servlet,位于:http://localhost:8080/manager/jmxproxy。例如,尝试此查询:

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

通过一些简单的grep和脚本编写,你可以轻松远程监控你的应用程序。注意,tomcat:tomcat是在conf/tomcat-users.xml中拥有manager-jmx角色的用户的用户名/密码。


1
谢谢Tomasz,我会尝试一下。我认为我不能使用代理servlet,因为它在管理器下面,但不幸的是由于某种原因,管理器似乎已经从安装中删除了 - 管理员目录存在,但管理器不存在。 - Alex P
1
我尝试使用上述的curl/jmxproxy,但它只返回了404错误,所以我认为管理器可能出现了问题。我将尝试按照上面建议的方式在显式端口上启用JMX,看看是否有效。感谢大家的帮助! - Alex P

3
你可以部署 jolokia.war,然后以 JSON 格式(无需管理器)检索 mbean 值: 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 +。

2
您可以使用通配符来避免引用 http-nio-8080 或 http-bio-8080,这将带来所有的线程池:curl -XGET 'http://localhost:8080/jolokia/read/Catalina:name=*,type=ThreadPool?ignoreErrors=true' - Gabriel Belingueres

2

对于更企业级的解决方案,我在我们的生产环境中使用了New Relic。

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


很棒的工具。可惜定价疯狂了。 - Tommy

0

现在有更便宜的工具可用:我正在使用这个jar包:https://docs.cyclopsgroup.org/jmxterm 您可以通过shell/batch脚本自动化它。我对输出进行了正则表达式处理,并让prometheus轮询它以在grafana中显示。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接