我的应用程序在docker中运行核心操作系统和Ubuntu。如何从这些系统收集线程转储以分析性能问题我尝试了以下命令,但不起作用:
kill -3 jstack docker exec appsnap
i5desfxk1#
我有一个java应用程序在docker中运行,我使用:docker exec -it <containerName> jstack > someFile.txt只是确保定期收集它,以便更好地了解它。同样,您可以使用像yourkit这样的应用程序来为您完成此操作
java
docker exec -it <containerName> jstack > someFile.txt
yourkit
bvhaajcl2#
在https://access.redhat.com/solutions/18178上有几个线程转储外壳脚本可能会对您有所帮助(在底部的附件下)。基本用法:
sh ./threaddump_linux.sh JAVA_PID
您必须将其添加到您的Dockerfile或exec中的容器中,并手动安装和运行它。使用它们的说明(以及其他线程转储技术)在该页面上
kcwpcxri3#
根据容器的构建方式,jstack可能不可用:
jstack
$ docker exec -it mycontainer jstack OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: exec: "jstack": executable file not found in $PATH: unknown
您必须首先在容器中安装JDK包,这似乎有点过分。有一件事对我很有效,那就是使用Quit信号方法来获得堆栈转储。这应该适用于所有容器,而不仅仅是Ubuntu。要生成转储,请附加到容器并找到Java进程的ID。容器内的PID与容器外的不同。
UPDATE:如果能找到合适的PID,您可以在容器外(宿主机上)向进程发送QUIT信号。
QUIT
您可能会发现容器中没有安装pidof,在某些情况下甚至ps实用程序。如果所有操作都失败,您可以在/proc文件系统中找到该ID:
pidof
ps
/proc
$ docker exec -it mycontainer /bin/sh sh-4.2$ find /proc -maxdepth 2 -name "cmdline" -exec grep '[j]ava' '{}' \; Binary file /proc/1709/cmdline matches
我们需要的PID是1709。如果find也不可用,您可以使用cat /proc/<PID>/cmdline手动搜索/proc中的进程目录。现在将退出信号发送到该PID(同样,它在容器中):
find
cat /proc/<PID>/cmdline
sh-4.2$ kill -QUIT 1709
现在,您必须找出进程的stdout去了哪里。在我的例子中,我很幸运,stdout最终出现在停靠器日志中(在主机上):
stdout
$ docker logs --since 1m mycontainer 2022-10-19 09:33:01 Full thread dump OpenJDK 64-Bit Server VM (11.0.5+10-LTS mixed mode, sharing): Threads class SMR info: [ .... ]
3条答案
按热度按时间i5desfxk1#
我有一个
java
应用程序在docker中运行,我使用:docker exec -it <containerName> jstack > someFile.txt
只是确保定期收集它,以便更好地了解它。
同样,您可以使用像
yourkit
这样的应用程序来为您完成此操作bvhaajcl2#
在https://access.redhat.com/solutions/18178上有几个线程转储外壳脚本可能会对您有所帮助(在底部的附件下)。
基本用法:
您必须将其添加到您的Dockerfile或exec中的容器中,并手动安装和运行它。
使用它们的说明(以及其他线程转储技术)在该页面上
kcwpcxri3#
根据容器的构建方式,
jstack
可能不可用:您必须首先在容器中安装JDK包,这似乎有点过分。
有一件事对我很有效,那就是使用Quit信号方法来获得堆栈转储。这应该适用于所有容器,而不仅仅是Ubuntu。
要生成转储,请附加到容器并找到Java进程的ID。容器内的PID与容器外的不同。
UPDATE:如果能找到合适的PID,您可以在容器外(宿主机上)向进程发送
QUIT
信号。您可能会发现容器中没有安装
pidof
,在某些情况下甚至ps
实用程序。如果所有操作都失败,您可以在/proc
文件系统中找到该ID:我们需要的PID是1709。如果
find
也不可用,您可以使用cat /proc/<PID>/cmdline
手动搜索/proc
中的进程目录。现在将退出信号发送到该PID(同样,它在容器中):
现在,您必须找出进程的
stdout
去了哪里。在我的例子中,我很幸运,stdout
最终出现在停靠器日志中(在主机上):