【问题标题】:Apache Tomcat Request ThreadsApache Tomcat 请求线程
【发布时间】:2011-08-03 02:57:34
【问题描述】:

我们有一个应用程序泄漏了一点内存,这有点轻描淡写。

我正在使用jvisualvm 尝试找出导致问题的原因。

我看到线程数以以下名称开头的线程增长了很多:http-8080- 例如:http:8080-42

我的第一个猜测是这些线程中的每一个都是来自客户端的请求,因为每个客户端请求都在其自己的线程中处理。

我的问题是这些线程已经运行了很长时间(到目前为止 10 分钟)。

我的问题是这样的:

我的假设正确吗? 如果是这样,为什么线程运行这么长时间?肯定不能一直忙于满足客户的要求吗?

【问题讨论】:

  • 这些线程有可能是会话线程吗?

标签: java multithreading tomcat


【解决方案1】:

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 ) - 在 org.apache.tomcat.util.net.JIoEndpoint 的 java.lang.Object.wait(Object.java:485) 等待 (一个 org.apache.tomcat.util.net.JIoEndpoint$Worker) $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) 锁定可拥有的同步器:- 无
  • 是的,他们只是在等待更多的连接——完全符合预期(和理想的行为)。 :)
【解决方案2】:

一般来说,应用服务器会预先创建多个线程。应用服务器不仅会创建它们,还会保留线程。这称为线程池。服务器将接受一个请求并将其分派给一个线程,当该请求完成时,服务器将向该线程分派一个新请求。

线程创建开销相当昂贵,因此处理许多请求从共享线程中受益匪浅。为了回答您的问题,由服务器创建的调度线程(假设没有发生严重的运行时错误)将在服务器的生命周期内有效。

至于您所看到的,如果您看到许多线程正在启​​动,那么应用程序的其他部分可能会分叉线程,这是一个完全独立的问题。

重要的是要知道您的 tomcat 服务器不应该为每个请求创建新线程(再次笼统地说)它应该重用线程。

【讨论】:

    【解决方案3】:

    检查 tomcat 连接器配置。注意maxThreads等线程池配置。一个常见的错误是只增加maxThreads 而没有实际“调整”。如果你配置了一个不必要的大池,它会导致大量的空闲线程。这不会有什么好处。

    尽管很明显,但仅作记录,TIMED_WAITING 线程将超时,而 WAITING 线程将等待notify()notifyAll()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-01
      • 2014-11-16
      • 2021-05-21
      • 2017-03-24
      • 2014-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多