web-dev-qa-db-ja.com

Tomcatの断続的なスローダウン、無反応、ハング

私は、Tomcatサーバーの断続的な速度低下の原因を突き止めようと努めてきました。週に数回スローダウンが発生し、Tomcatが応答を停止するか、リクエストの処理に数分かかります。稼働時間で示されるように、(Linux)ボックスのCPU負荷は、通常1〜2から30を超えます。その後、物事は徐々にうまくいき、おそらく10分程度ですべてが正常に戻ります。

私たちはApacheをフロントエンドとして使用し、Postgresをデータベースに使用しています。ログを掘り下げて、問題の原因を突き止めています。景気減速の時期の前後で、需要が明らかに増加していることに気づきませんでした。

私が見つけたのは、減速の直前に、Tomcatが約3分半スリープするように見えることが複数回あることです。その間、ログにはエントリがなく、Tomcatからデータベースへのクエリもありません。少し仮眠した後、Tomcatは目を覚まし、その間にバックアップされたすべてのものを処理しようと猛烈に開始し、データベースとCPUの負荷が高くなり、応答時間が遅くなります。

Tomcatが昼寝時に何をしているのかを試して理解するために、ログを監視するスクリプトを設定し、ログに3分間アクティビティがない場合に、kill -3シグナルを送信してスレッドダンプを取得します。残念ながら、この信号はTomcatを起動させないため、スレッドダンプは、それ自体が起動して処理を再開するまで発生しません。

ApacheとPostgresは、3分30秒のギャップの間、まだ目覚めていてアクティブです。これらのログは、Tomcatに関連しないアクティビティがこれらの期間中に継続していることを示しています。

Tomcatのバージョンは5.0.28です。

考え、提案?私はTomcatでの作業にかなり慣れているので、あまり知識がないと思ってください。


Alexの提案に従って詳細なガベージコレクションをアクティブ化した後、問題の発生を2回記録し、フルGCが原因であることがわかりました。

04:21:55.648491500 [GC 1035796K->933637K(1041984K), 0.3407580 secs]
04:21:56.012832500 [Full GC[Unloading class Sun.reflect.GeneratedMethodAccessor633]
04:22:38.003920500 [Unloading class Sun.reflect.GeneratedSerializationConstructorAccessor39]
04:22:38.004051500 [Unloading class Sun.reflect.GeneratedConstructorAccessor102]
04:22:38.004392500 [Unloading class Sun.reflect.GeneratedConstructorAccessor98]
04:22:38.004533500 [Unloading class Sun.reflect.GeneratedSerializationConstructorAccessor40]
04:22:38.004716500 [Unloading class Sun.reflect.GeneratedMethodAccessor634]
04:22:38.004808500 [Unloading class Sun.reflect.GeneratedConstructorAccessor90]
04:22:38.004889500 [Unloading class Sun.reflect.GeneratedConstructorAccessor95]
04:22:38.005044500 [Unloading class Sun.reflect.GeneratedMethodAccessor632]
04:25:18.688916500  933637K->154281K(1041984K), 202.6760940 secs]

今、私はそれを防ぐために物事を調整する方法を理解する必要があります。 (提案は歓迎します。)

アレックスとメインガイの助けをありがとう。

6
ecto

上記のステップ1は、Tomcat起動スクリプトを変更して追加することです。

-verbose:gc -XX:+PrintGCTimeStamps -XX:+PrintGCDetails  

スローダウンが発生したら、catalina.outで「FullGC」または多くのGCなどを探します...

まだ行っていない場合は、このボックスでTomcatが実行されると仮定して、Tomcatヒープサイズを利用可能なメモリの約1/2から3/4に増やします。たとえば、最大ヒープを768メガバイトに設定するには、次のように追加します。

-Xmx768M

Java_OPTS

Ubuntu 10.04を使用している場合、これらの設定は通常/ etc/default/Tomcat6にあります。

5
Mainguy

Javaヒープがガベージで使用されていないために、ヒープがディスクにスワップアウトされました) while。完全なコレクションが必要な場合、そのメモリをスワップインする必要があります。

この場合、あなたの答えはやや直観に反します:Javaヒープのサイズを減らすか、または他のものがRAMスワッピング。私たちの場合、一部の夜間バッチジョブは大量のRAMを使用したため、古い世代がディスクにスワップアウトされました。そのため、翌朝必要な最初のフルGCはFOREVER(180秒以上、見ています)。

また、並行マークスイープコレクターを試すこともできます。これにより、多くの作業を並行して実行することにより、フルGC時間を短縮できます。これは私が見た中で最高のドキュメントです。この件に関しては、Sunのブログもいくつかあります: http://www.Oracle.com/technetwork/Java/gc-tuning-5-138395.html

3
rmalayter

詳細なガベージコレクションをアクティブにして、ガベージコレクションの一時停止かどうかを確認してください。巨大なヒープ、大量のオブジェクトの割り当てとスワップが長い休止を引き起こす可能性があると思いますが、それは非常に珍しく聞こえます。

1
alex