Linux 如何从tomcat自动获取线程转储

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10154910/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 05:47:03  来源:igfitidea点击:

How to automatically get thread dumps from tomcat

javalinuxmultithreadingshellmonitoring

提问by ThinkFloyd

We had some issues of thread pile upswith production tomcat server so I wanted to setup some cron to to periodically check thread dumps and send alert email if something is wrong. To do this we need to take thread dumps in file from shell script but I am unable to do that. From shell I can issue KILL -3 <PID>at periodic intervals but the problem is that dump goes to catalina.out which contains GBs of data because of which pulling out only thread dump is painful process. Some discussion threads suggested usage of "jstack" and redirect output to a file but that also is not working and giving this error:

我们在生产tomcat服务器上遇到了一些线程堆积的问题,所以我想设置一些cron来定期检查线程转储并在出现问题时发送警报电子邮件。为此,我们需要从 shell 脚本中获取文件中的线程转储,但我无法做到这一点。从 shell 我可以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)

This bug seems to be open with java team.

这个错误似乎与java团队一起开放。

Any other suggestion to intelligently take and analyze thread dumps? Or script to parse huge catalina.out and get just thread dumps out of it?

还有其他建议可以智能地获取和分析线程转储吗?或者脚本来解析巨大的 catalina.out 并从中获取线程转储?

采纳答案by nsfyn55

Checkout this article about scheduling thread dumps. I think it is exactly what you are trying to do.

查看这篇关于调度线程转储的文章。我认为这正是你想要做的。

回答by Arnost Valicek

Another option could be JMX - ThreadMXBean. This was discussed at SO question How do I create a thread dump via JMX?

另一种选择可能是 JMX - ThreadMXBean。这在 SO 问题如何通过 JMX 创建线程转储中讨论过

回答by ThinkFloyd

One quick way I figured out was (mis)using javamelody. We use it to monitor various aspects of application and it also provides visual & usual ways to look at current threads so I wrote small shell script to hit "http://IP:PORT/SERVICE/monitoring?part=threadsDump" every minute and dump response in a file. If response contains any blocked thread script will take thread dumps every 5 seconds. This helps upto some extent but when problem worsens and server stalls, javamelody also stop responding.

我想出的一种快速方法是(错误)使用javamelody。我们用它来监控应用程序的各个方面,它还提供了查看当前线程的可视化和常用方法,所以我写了一个小的 shell 脚本来每分钟点击“http://IP:PORT/SERVICE/monitoring?part=threadsDump”在文件中转储响应。如果响应包含任何阻塞的线程脚本将每 5 秒进行一次线程转储。这在一定程度上有帮助,但是当问题恶化和服务器停止时,javamelody 也会停止响应。