3

本番のTomcatサーバーでスレッドがパイルアップするという問題がいくつかあったため、定期的にスレッドダンプをチェックし、何か問題がある場合にアラートメールを送信するようにcronをセットアップしたいと考えました。これを行うには、シェル スクリプトからファイル内のスレッド ダンプを取得する必要がありますが、それができません。シェルからKILL -3 <PID>定期的に発行することはできますが、問題は、ダンプが catalina.out に送られることです。これには何 GB ものデータが含まれているため、スレッド ダンプだけを取り出すのは面倒なプロセスです。一部のディスカッション スレッドでは、「jstack」を使用して出力をファイルにリダイレクトすることを提案しましたが、これも機能せず、次のエラーが発生します。

-bash-3.2# java -version
java version "1.6.0_26"
Java(TM) SE Runtime Environment (build 1.6.0_26-b03)
Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02, mixed mode)
-bash-3.2# uname -a
Linux ip-10-130-225-20 2.6.16.33-xenU #2 SMP Wed Aug 15 17:27:36 SAST 2007 x86_64 x86_64 x86_64 GNU/Linux

-bash-3.2# sudo /usr/java/jdk1.6.0_24/bin/jstack -F 15668
Attaching to process ID 15668, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 19.1-b02
Deadlock Detection:

No deadlocks found.

Thread 8183: (state = BLOCKED)
Error occurred during stack walking:
sun.jvm.hotspot.debugger.DebuggerException: sun.jvm.hotspot.debugger.DebuggerException: get_thread_regs failed for a lwp
    at sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal$LinuxDebuggerLocalWorkerThread.execute(LinuxDebuggerLocal.java:152)
    at sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal.getThreadIntegerRegisterSet(LinuxDebuggerLocal.java:466)
    at sun.jvm.hotspot.debugger.linux.LinuxThread.getContext(LinuxThread.java:65)
    at sun.jvm.hotspot.runtime.linux_amd64.LinuxAMD64JavaThreadPDAccess.getCurrentFrameGuess(LinuxAMD64JavaThreadPDAccess.java:92)
    at sun.jvm.hotspot.runtime.JavaThread.getCurrentFrameGuess(JavaThread.java:256)
    at sun.jvm.hotspot.runtime.JavaThread.getLastJavaVFrameDbg(JavaThread.java:218)
    at sun.jvm.hotspot.tools.StackTrace.run(StackTrace.java:76)
    at sun.jvm.hotspot.tools.StackTrace.run(StackTrace.java:45)
    at sun.jvm.hotspot.tools.JStack.run(JStack.java:60)
    at sun.jvm.hotspot.tools.Tool.start(Tool.java:221)
    at sun.jvm.hotspot.tools.JStack.main(JStack.java:86)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at sun.tools.jstack.JStack.runJStackTool(JStack.java:118)
    at sun.tools.jstack.JStack.main(JStack.java:84)
Caused by: sun.jvm.hotspot.debugger.DebuggerException: get_thread_regs failed for a lwp
    at sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal.getThreadIntegerRegisterSet0(Native Method)

このバグは Java チームで未解決のようです。

スレッド ダンプをインテリジェントに取得して分析するための他の提案はありますか? または、巨大な catalina.out を解析してスレッド ダンプだけを取得するスクリプトを作成しますか?

4

3 に答える 3

2

スレッド ダンプのスケジューリングに関するこの記事を確認してください。それはまさにあなたがやろうとしていることだと思います。

于 2012-05-07T12:45:13.120 に答える
1

別のオプションは、JMX-ThreadMXBeanである可能性があります。これはSOの質問で議論されました。JMXを介してスレッドダンプを作成するにはどうすればよいですか?

于 2012-04-14T17:00:47.743 に答える
0

私が理解した簡単な方法の1つは、 javamelodyを(誤って)使用することでした。アプリケーションのさまざまな側面を監視するために使用し、現在のスレッドを視覚的かつ通常どおりに確認する方法も提供するため、毎分「http://IP:PORT/SERVICE/monitoring?part=threadsDump」にアクセスする小さなシェル スクリプトを作成し、応答をファイルにダンプします。応答にブロックされたスレッドが含まれている場合、スクリプトは 5 秒ごとにスレッド ダンプを取得します。これはある程度は役立ちますが、問題が悪化してサーバーが停止すると、javamelody も応答しなくなります。

于 2012-05-07T12:37:34.630 に答える