Apache Tomcat 请求线程

7
我们有一个应用程序存在少量内存泄漏,少量是轻描淡写了。
我正在使用 jvisualvm 尝试找出问题所在。
我发现线程计数增长相当多,以名称开头的线程为例:http-8080- 例如:http:8080-42 我的第一次猜测是每个线程都是客户端请求的命中,因为每个客户端请求都在自己的线程中处理。
但我的问题是这些线程已经运行了很长时间(到目前为止已经10分钟)。 我的问题是: 我的假设是否正确?如果是,为什么线程运行时间如此之长?它肯定不可能还在忙于服务客户端请求吧?

这些线程可能是会话线程吗? - Koekiebox
3个回答

9

Tomcat总是有一些等待的HTTP线程,例如如果我们查看默认连接器设置:

<Connector port="80" maxHttpHeaderSize="8192"
              maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
              enableLookups="false" redirectPort="8443" acceptCount="100"
              connectionTimeout="20000" disableUploadTimeout="true" />

我们可以看到,至少应该有25个线程处于活动状态,但等待连接(最多达到maxThreads限制)。这由min和maxSpareThreads属性控制。
JVisual VM是如何说明线程正在等待或锁定资源等等的?

所有这些线程都处于等待状态:“http-8080-24” - 线程t@70 java.lang.Thread.State: WAITING at java.lang.Object.wait(Native Method)
  • waiting on <96c084> (a org.apache.tomcat.util.net.JIoEndpoint$Worker) at java.lang.Object.wait(Object.java:485) at org.apache.tomcat.util.net.JIoEndpoint$Worker.await(JIoEndpoint.java:414) at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:440) at java.lang.Thread.run(Thread.java:619)锁定自有同步器:
- Koekiebox
是的,它们只是在等待更多的连接 - 这是完全预期的(也是期望的行为)。 :) - Michael

2
一般来说,应用服务器会预先创建一些线程。这些线程不仅由应用服务器创建,而且会一直保留。这就是所谓的线程池。服务器将获取请求并将其分派到一个线程,当该请求完成时,服务器将向该线程分派一个新请求。
由于线程创建开销相当昂贵,因此处理许多请求非常受益于共享线程。回答您的问题,分派由服务器创建的线程(假设没有严重的运行时错误)将在服务器的生命周期内存在。
至于您看到的情况,如果您看到很多线程被启动,那么应用程序的其他部分可能正在分叉线程,这是完全不同的问题。
重要的是要知道,您的Tomcat服务器不应为每个请求创建新线程(一般而言),而应重复使用线程。

2
检查Tomcat连接器配置。特别注意maxThreads和其他线程池配置。一个常见的错误是只增加maxThreads,而没有真正进行"调优"。如果您配置了一个不必要的大池,将会导致大量空闲线程。这样做没有任何好处。
虽然这很明显,但为了记录,TIMED_WAITING线程将超时,而WAITING线程将静待notify()notifyAll()

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