我有一个令人讨厌的问题,负载均衡的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工作者。
是什么导致了这个问题?我该如何进一步调查呢?我该怎么做才能解决它?
提前致谢。
答案 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可能表现得一样。你可以尝试的事情是: