10

負荷分散されたTomcatサーバーがハングアップしているという厄介な問題があります。どんな助けでも大歓迎です。

システム

ロードバランサーとして機能する別のサーバーの背後にある3台のサーバーで、HotSpot Server 14.3-b01(Java 1.6.0_17-b04)でTomcat6.0.26を実行しています。ロードバランサーはApache(2.2.8-1)+ MOD_JK(1.2.25)を実行します。すべてのサーバーはUbuntu8.04を実行しています。

Tomcatには、AJPコネクタとHTTPコネクタの2つのコネクタが設定されています。AJPはロードバランサーで使用され、HTTPは開発チームが選択したサーバーに直接接続するために使用されます(そうする理由がある場合)。

すぐに説明する問題を診断して修正するために、TomcatサーバーにLambdaProbe1.7bをインストールしています。

問題

問題は次のとおりです。アプリケーションサーバーが起動してから約1日後、JKステータスマネージャはERRTomcat2などのステータスのレポートを開始します。それは単にこの状態で立ち往生するでしょう、そして私がこれまでに見つけた唯一の修正はボックスをsshしてTomcatを再起動することです。

また、Tomcatサーバーがこの状態にある場合、JKステータスマネージャーの更新に非常に長い時間がかかることにも言及する必要があります。

最後に、JKステータスマネージャでスタックしたTomcatの「ビジー」カウントは常に高く、それ自体はダウンしません。Tomcatサーバーを再起動し、待機してから、JKのワーカーをリセットする必要があります。

分析

各Tomcat(AJPとHTTP)に2つのコネクタがあるので、HTTPコネクタを介してアプリケーションに接続できます。アプリケーションはこのように非常に高速に動作します。このサーバーを使用しているのは私だけなので、これは完全に正常です(JKがこのTomcatへの要求の委任を停止したため)。

問題をよりよく理解するために、応答しなくなったTomcatと、最近再起動された別のTomcat(たとえば、1時間前)からスレッドダンプを取得しました。

JKに正常に応答しているインスタンスは、ほとんどの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

4 に答える 4

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を多用する環境(MVCフレームワークではなくtaglibs)で最適に機能しました。

于 2010-06-15T18:24:33.103 に答える
1

最初にログファイルを確認してください。

デフォルトのログ ファイルは /var/log/daemon.log にあると思います。(このファイルには tomcat からのログだけが含まれているわけではありません)

于 2010-05-26T12:11:50.717 に答える
1

キープアライブ時間の設定を確認してください。スレッドをキープアライブ状態にしているようで、タイムアウトしません。サーバーが適切な時間内にクライアントの切断を検出していないようです。関連するタイムアウト変数とカウント変数がいくつかあります。

于 2010-06-05T20:44:54.257 に答える
1

Weblogic でも同様の問題が発生しました。原因は、ネットワーク応答を待機しているスレッドが多すぎて、Weblogic がメモリ不足になったことです。Tomcat はおそらく同じように動作します。あなたが試すことができることは次のとおりです。

  • 接続のタイムアウト値を減らします。
  • 同時接続の合計量を減らして、その量に達したときに tomcat が新しいスレッドを開始しないようにします。
  • 簡単に修正できますが、根本的な原因は修正されません。ログにはまだ表示されていなくても、Tomcat がメモリ不足の状態になっている可能性があります。前述のように tomcat のメモリを増やします。
于 2010-06-18T10:27:33.350 に答える