Tomcat停止响应JK请求

时间:2010-05-17 16:27:12

标签: java tomcat tomcat6 mod-jk

我有一个令人讨厌的问题,负载均衡的Tomcat服务器正在挂断。任何帮助将不胜感激。

系统

我在位于另一台充当负载均衡器的服务器后面的三台服务器上运行HotSpot Server 14.3-b01(Java 1.6.0_17-b04)上的Tomcat 6.0.26。负载均衡器运行Apache(2.2.8-1)+ MOD_JK(1.2.25)。所有服务器都运行Ubuntu 8.04。

Tomcat配置了2个连接器:AJP连接器和HTTP连接器。 AJP将与负载均衡器一起使用,而开发团队使用HTTP直接连接到所选服务器(如果我们有理由这样做)。

我在Tomcat服务器上安装了Lambda Probe 1.7b,以帮助我快速诊断和解决问题。

问题

问题在于:大约1天后,应用程序服务器启动,JK状态管理器开始报告状态ERR,例如Tomcat2。它只会停留在这种状态,到目前为止我发现的唯一修复是ssh框并重启Tomcat。

我还必须提一下,当处于此状态的Tomcat服务器时,JK状态管理器需要花费更长时间才能刷新。

最后,JK状态管理器上卡住的Tomcat的“繁忙”计数总是很高,并且本身不会下降 - 我必须重新启动Tomcat服务器,等待,然后在JK上重置worker。

分析

由于每个Tomcat(AJP和HTTP)上有2个连接器,我仍然可以通过HTTP连接到应用程序。这个应用程序工作正常,非常非常快。这是完全正常的,因为我是唯一使用此服务器的人(因为JK停止将请求委托给此Tomcat)。

为了更好地理解这个问题,我从已经没有响应的Tomcat中获取了一个线程转储,并且从最近重新启动的另一个(例如,1小时前)开始。

正常响应JK的实例显示处于“Runnable”状态的大多数TP-ProcessorXXX线程,具有以下堆栈跟踪:

java.net.SocketInputStream.socketRead0 ( native code )
java.net.SocketInputStream.read ( SocketInputStream.java:129 )
java.io.BufferedInputStream.fill ( BufferedInputStream.java:218 )
java.io.BufferedInputStream.read1 ( BufferedInputStream.java:258 )
java.io.BufferedInputStream.read ( BufferedInputStream.java:317 )
org.apache.jk.common.ChannelSocket.read ( ChannelSocket.java:621 )
org.apache.jk.common.ChannelSocket.receive ( ChannelSocket.java:559 )
org.apache.jk.common.ChannelSocket.processConnection ( ChannelSocket.java:686 )
org.apache.jk.common.ChannelSocket$SocketConnection.runIt ( ChannelSocket.java:891 )
org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run ( ThreadPool.java:690 )
java.lang.Thread.run ( Thread.java:619 )

卡住的实例显示处于“等待”状态的大多数(全部?)TP-ProcessorXXX线程。它们具有以下堆栈跟踪:

java.lang.Object.wait ( native code )
java.lang.Object.wait ( Object.java:485 )
org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run ( ThreadPool.java:662 )
java.lang.Thread.run ( Thread.java:619 ) 

我不知道Tomcat的内部结构,但我推断“等待”线程只是坐在线程池上的线程。因此,如果它们是在线程池内等待的线程,为什么Tomcat不会让它们处理来自JK的处理请求?

编辑:我不知道这是否正常,但Lambda Probe在状态部分向我展示了KeepAlive状态下有很多线程。这在某种程度上与我遇到的问题有关吗?

解?

所以,正如我之前所说的,我发现的唯一修复是停止Tomcat实例,停止JK工作,等待后者的忙碌计数慢慢下降,再次启动Tomcat ,并再次启用JK工作者。

是什么导致了这个问题?我该如何进一步调查呢?我该怎么做才能解决它?

提前致谢。

4 个答案:

答案 0 :(得分:3)

您是否配置了JVM内存设置和垃圾收集?您可以在设置CATALINA_OPTS

的地方执行此操作

的示例:

CATALINA_OPTS="$CATALINA_OPTS -server -Xnoclassgc -Djava.awt.headless=true"
CATALINA_OPTS="$CATALINA_OPTS -Xms1024M -Xmx5120M -XX:MaxPermSize=256m"
CATALINA_OPTS="$CATALINA_OPTS -XX:-UseParallelGC"
CATALINA_OPTS="$CATALINA_OPTS -Xnoclassgc"

GC设置最好有多种理念。这取决于您正在执行的代码类型。上面的配置最适合JSP密集型环境(taglibs而不是MVC框架)。

答案 1 :(得分:2)

检查您的保持活动时间设置。看起来你的线程已进入keepalive状态,并且它们没有超时。您的服务器似乎未在合理的时间内检测到客户端断开连接。涉及多个超时和计数变量。

答案 2 :(得分:1)

首先检查您的日志文件。

我认为默认日志文件位于/var/log/daemon.log中。 (此文件不包含tomcat中的日志)

答案 3 :(得分:1)

我和Weblogic有类似的问题。原因是有太多线程在等待网络响应而Weblogic正在耗尽内存。 Tomcat可能表现得一样。你可以尝试的事情是:

  • 减少连接的超时值。
  • 减少并发连接的总量,以便在达到该数量时tomcat不会启动新线程。
  • 轻松修复,但没有更正根本原因:可能是tomcat处于内存不足状态,即使它还没有显示在日志中。像之前描述的那样增加tomcat的内存。
相关问题