ubuntu 如何从docker获取线程转储

nfzehxib  于 2022-10-27  发布在  Docker
关注(0)|答案(3)|浏览(126)

我的应用程序在docker中运行核心操作系统和Ubuntu。如何从这些系统收集线程转储以分析性能问题
我尝试了以下命令,但不起作用:

kill -3
jstack
docker exec
appsnap
i5desfxk

i5desfxk1#

我有一个java应用程序在docker中运行,我使用:docker exec -it <containerName> jstack > someFile.txt
只是确保定期收集它,以便更好地了解它。
同样,您可以使用像yourkit这样的应用程序来为您完成此操作

bvhaajcl

bvhaajcl2#

https://access.redhat.com/solutions/18178上有几个线程转储外壳脚本可能会对您有所帮助(在底部的附件下)。
基本用法:

sh ./threaddump_linux.sh JAVA_PID

您必须将其添加到您的Dockerfile或exec中的容器中,并手动安装和运行它。
使用它们的说明(以及其他线程转储技术)在该页面上

kcwpcxri

kcwpcxri3#

根据容器的构建方式,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信号。

您可能会发现容器中没有安装pidof,在某些情况下甚至ps实用程序。如果所有操作都失败,您可以在/proc文件系统中找到该ID:

$ 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(同样,它在容器中):

sh-4.2$ kill -QUIT 1709

现在,您必须找出进程的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:
[ .... ]

相关问题