jps、jstat、jstack 等命令显示“<pid> 未找到”

Commands like jps, jstat, jstack, etc show "<pid> not found"

我 运行 Tomcat 9 在 Ubuntu 20.04 OS 上使用 OpenJDK 64 位服务器 VM(构建 25.275-b01,混合模式)。 当我尝试使用 jstat、jstack 等收集诊断信息时,我看到 PID not found。 jps 也无法识别 Tomcat 进程 ID。

我查看了一些帖子,例如 one, two, three, four 等,但是其中 none 的答案帮助我解决了我的问题!

即使我传递 Tomcat 进程的用户名是 运行,jstat 也找不到该进程:sudo -u tomcat jstat -gc 476174 5000

以防万一:

  1. 我可以看到 Tomcat 进程是从 -Djava.io.tmpdir=/tmp 开始的 此文件夹归 root 用户所有,但已启用完全权限 (777)。
  2. 当 Tomcat 进程启动时,我可以看到一个名为 systemd-private-e6d8b5dc224848f8a64a3e943ac2e9c4-tomcat9.service-UH5knj 的文件夹(服务后的最后几个字符 - 每次进程重新启动时都会更改)被创建,所有者为 root (可能是因为我使用 sudo service tomcat9 start 启动 tomcat 服务)并且此文件夹具有 rwx------.
  3. 的权限

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

谢谢, 肖巴纳

所有这些工具(jstack、jmap、jstat...)通过 /tmp 目录依赖于目标 JVM 的

显然 Tomcat 运行 在不同的挂载命名空间中,因此其 /tmp 目录与当前 shell 的 /tmp 不同.为了验证这一点,运行

readlink /proc/$$/ns/mnt
readlink /proc/<java_pid>/ns/mnt

并检查 inode 个数字是否不同。

Unfo运行最近,JDK 8 个工具不支持 Linux 命名空间。您可以尝试 nsenter 在 Tomcat 的命名空间下启动这些工具。

或者简单地使用 JDK 11(或更新的)工具,它们支持开箱即用的容器(以及命名空间)。他们还与 运行ning 在 JDK 8 下的应用程序一起工作,例如来自 JDK 11 的 jstack 可以转储 JDK 8 进程的线程。

或者,有一个小 jattach utility which can be used in place of jstack, jmap, and jcmd. It also supports containers out of the box. It does not require installation - there is just a single standalone binary

In Ubuntu 20 Tomcat 9 服务 运行s 在私有 tmp space 默认情况下,因此 java 工具无法找到它的 pid.

此私有 tmp 设置在 /lib/systemd/system/tomcat9.service 中定义为 PrivateTmp。默认设置为“是”。您可以直接编辑该文件,但推荐的更改方法是使用此命令创建覆盖文件:

sudo systemctl edit tomcat9

在文件中添加以下内容并保存:

[Service]
PrivateTmp=no
ReadWritePaths=/tmp/

它将使用您的内容创建此文件:/etc/systemd/system/tomcat9.service.d/override.conf

然后你需要重新加载systemd守护进程并重启Tomcat:

sudo systemctl daemon-reload
sudo systemctl restart tomcat9

您现在应该可以直接使用 sudo 调用 java 工具,例如sudo jstat...。出于某种原因,当我尝试 运行 它作为 tomcat 用户使用 sudo -u tomcat jstat...

时它不起作用