JBossを使用して2つのWARを実行しています。 1つはWebアプリで、もう1つはWebサービスです。 Webアプリは、別のマシン上のデータベースにアクセスし、Webサービスにリクエストを送信します。 Webサービスは、他のマシンに対してJMS要求を行い、データを集約して返します。
最大のクライアントでは、月に1回程度JBoss JavaプロセスがすべてのCPUを100%使用します。JBossを実行しているマシンには8つのCPUがあります。この間もWebアプリにアクセスできますが、ページはロードに約3分。JBossを再起動すると、すべてが通常の状態に戻ります。
データベースマシンと他のすべてのマシンは正常であり、JBossを実行しているマシンのみが影響を受けます。メモリ使用量は正常です。ネットワークの使用率は正常です。 JBossログに疑わしいエラーメッセージはありません。
クライアントの実稼働環境にできるだけ近いテスト環境をセットアップし、同時ユーザー数の2倍もの負荷テストを実行しました。問題を再現するためのテスト環境を取得していません。
ここからどこにいきますか?どうすれば問題を絞り込むことができますか?
現在、私たちが持っている唯一の計画は、問題が本番環境で発生するまで待ってから、デバッグを行って原因を特定することです。これまでのところ、ダウンタイムを最小限に抑えるために、問題が発生したときにJBossを再起動したところです。次回それが起こったとき、彼らは開発者に見てもらうでしょう。問題は、次にそれが起こったときに、原因を特定するために何ができるかということです。
同じボックスに別のJBossインスタンスをセットアップし、Webサービスとは別にWebアプリをインストールすることができます。このようにして、次に問題が発生したときに、どのWARに問題があるかがわかります(コードであると想定)。しかし、これはそれをあまり絞り込みません。
JMXリモートを有効にする必要がありますか?このようにして、次に問題が発生したときにVisualVMに接続して、どのスレッドがCPUを使用していて、何をしているのかを確認できます。ただし、実稼働環境でJMXリモートを有効にすることには重大な欠点がありますか?
どのスレッドがCPUを消費しているかを確認し、スタックトレースを取得してそれらが何を行っているかを確認する別の方法はありますか?
他のアイデアはありますか?
ありがとう!
実行中のJVMにSIGQUITシグナルを送信して、各スレッドのスタックトレースをstdoutに出力できます。スタックトレースが出力されている間、すべてのスレッドがスリープ状態になると思いますが、これによってプロセスが強制終了されることはありません。
次に、リストされているスレッドIDを、スレッドごとのCPU使用率を確認するための推奨される方法と関連付けます。 prstat -L
Solarisの場合、top -H
Linuxの場合。 Javaスタックトレースのtidは16進数で出力されることに注意してください。トップまたはprstatの出力と比較する場合は、おそらく10進数に変換する必要があります。
スレッドダンプを行います。ただし、本番システムでは、本番環境では有効にしない特定のパラメーターを使用してJVMを起動しない限り、これを実行できません。この場合、JMXコンソールのjboss.system:type = ServerInfo mbeanを使用してスレッドダンプ(listThreadDump())を実行します。
コードを記述していない場合、スレッドダンプの出力はほとんど意味がありません。しかし、コードを書いた人はそれを理解できるかもしれません。スレッドダンプが役に立たないこれらの場合、私は「strace -fp <PID of JBoss' Java process> -o outfile.txt
"システムコールレベルで何が起こっているかについて別の見方をする。これは、消防ホースから飲むのと少し似ていますが、役立つ場合もあります。