0

我有不止一个 java 应用程序在单独的 docker 容器中运行。我正在尝试使用 jstat、jstack、jmap 等工具从容器内运行的 java 进程收集监控数据,例如 GC 日志、线程转储、堆转储。是否可以从主机(外部容器)捕获此信息?

我是集装箱世界的新手。我知道主机和容器的 PID 命名空间是不同的。当我jstack <PID> > thread_dump.txt从主机执行时,它显示错误消息:无法打开套接字文件/proc/root/tmp/.java_pid:目标进程在 10500 毫秒内没有响应或未加载 HotSpot VM

其中 PID 是来自主机 PID 命名空间的进程 ID。

当我jstack在容器 ( docker exec -it <container_id_or_name>) 内执行时,它能够捕获线程转储。

其中 PID 是容器 PID 命名空间中的进程 ID。

关于如何解决这个问题的任何提示?

4

2 回答 2

3

jattach工具正是为此目的服务的。该项目是免费和开源的。

例子:

  • jattach <pid> threaddump(像 jstack 一样工作)
  • jattach <pid> inspectheap(像 jmap -histo 一样工作)
  • jattach <pid> jcmd GC.class_stats

<pid>主机命名空间中的 Java 进程 ID 在哪里。

作为奖励,jattach即使容器在没有安装 JDK 工具(jstack、jcmd 等)的情况下运行 JRE 也能正常工作。

于 2021-08-31T16:12:30.940 回答
1

您应该使用的命令是:

docker exec -i <container_id_or_name> <your_monitoring_command>

该命令将在容器内执行,但它会将其输出 (by -i) 报告给调用方控制台。

于 2021-08-31T13:17:50.420 回答