乐趣区

利用VisualVm远程监控Java进程

原文地址
本文介绍利用 VisualVm 和 jstatd 来远程监控 Java 进程的方法。
要实现远程监控 Java 进程,必须在远程主机(运行 Java 程序的主机)上跑一个 jstatd 进程,这个进程相当于一个 agent,用来收集远程主机上的 JVM 运行情况,然后用 VisualVm 连接到这个 jstatd,从而实现远程监控的目的。
第一步:在远程主机上启动 jstatd
要注意的是,jstatd 是一个 RMI server application,因此在启动时支持 java.rmi properties。
根据 jstatd 文档,我们需要在启动 jstatd 时提供一个 security policy 文件:
grant codebase “file:${java.home}/../lib/tools.jar” {
permission java.security.AllPermission;
};
然后运行下面命令启动:
jstatd -J-Djava.security.policy=jstatd.all.policy
不过这里有一个陷阱,见 SO 上的这个提问:VisualVm connect to remote jstatd not showing applications。在启动时还得指定 rmi server hostname,否则 VisualVm 无法看到远程主机上的 Java 进程。所以正确的命令应该是这样:
jstatd -J-Djava.security.policy=jstatd.all.policy -J-Djava.rmi.server.hostname=<host or ip>
远程主机的 hostname 可以随便填,只要 VisualVm 能够 ping 通这个 hostname 就行了。所以说下面这几种情况都是可行的:

远程主机没有 DNS name,但 VisualVm 所在主机的 /etc/hosts 里配置了 some-name <ip-to-remote-host>。jstatd 启动时指定 -J-Djava.rmi.server.hostname=some-name,VisualVm 连接 some-name。
远程主机经过层层 NAT,它的内部 ip 比如是 192.168.xxx.xxx,它的对外的 NAT 地址是 172.100.xxx.xxx。jstatd 启动时指定 -J-Djava.rmi.server.hostname=172.100.xxx.xxx,VisualVm 连接 172.100.xxx.xxx。
上面两种方式混合,即在 VisualVm 所在主机的 /etc/hosts 里配置 some-name <ip-to-remote-host-nat-address>。jstatd 启动时指定 -J-Djava.rmi.server.hostname=some-name,VisualVm 连接 some-name。

还有要注意一点,运行 jstatd 的用户必须和运行 Java 程序的用户相同,或者是 root,否则会监控不到远程主机上的 Java 进程。
第二步:启动 VisualVm
在你的机器上运行 jvisualvm 启动 VisualVm。按照下面步骤添加远程主机:
第一步

第二步

第三步

你就能看到远程主机上的 Java 进程了。
需要注意的是如果你点开一个远程进程,那么你会发现有些信息是没有的,比如:CPU、线程、和 MBeans。这是正常的,如果需要这些信息(就像监控本地 Java 进程一样),那么就需要用 JMX,相关内容会在另一篇文章中讲解。
参考资料

VisualVm – Working with Remote Applications
jstatd
java.rmi Properties
VisualVm connect to remote jstatd not showing applications

退出移动版