JVisualVM除了可以方便监控本地Java应用外,也支持通过Remote节点远程监控Java进程。这样可以利用可视化界面更高效率地监控生产环境,定位CPU或者内存问题。

VisualVM连接远程节点有2种方式:jstatd和jmx。其中jstatd仅支持monitor,jmx才能支持threads和sampler。下面分别详细讲解。

一、Jstatd连接方式

在远程主机上启动Jstatd,需要先配置权限,否则会报如下security错误:

Could not create remote object
access denied ("java.util.PropertyPermission" "java.rmi.server.ignoreSubClasses" "write")
java.security.AccessControlException: access denied ("java.util.PropertyPermission" "java.rmi.server.ignoreSubClasses" "write")
    at java.security.AccessControlContext.checkPermission(AccessControlContext.java:472)
    at java.security.AccessController.checkPermission(AccessController.java:884)
    at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
    at java.lang.System.setProperty(System.java:792)
    at sun.tools.jstatd.Jstatd.main(Jstatd.java:139)

因此先在$JAVA_HOME/bin下创建一个jstatd.all.policy文件。内容如下:

grant codebase "file:${java.home}/../lib/tools.jar" {
  permission java.security.AllPermission;
};

注意:Java9之后的版本不存在文件tools.jar,据说按如下配置可行(本人未验证,请自行研究哈):

grant codebase "jrt:/jdk.jstatd" {
   permission java.security.AllPermission;
};
grant codebase "jrt:/jdk.internal.jvmstat" {
   permission java.security.AllPermission;
};

然后在$JAVA_HOME/bin下下启动jstatd:

jstatd -J-Djava.security.policy=jstatd.all.policy

在本地JVisualVM客户端上Remote下添加节点:

接下来选择对应的java进程就可以进行监控了。不过jstatd模式下,只能使用简单的Monitor,无法使用Sampler功能。如需Sampler,需使用JMX方式连接。

以下为Monitor截图:

二、JMX连接方式

JMX即Java virtual machine,是Java自带的开箱即用的管理工具和接口。

在远程主机启动应用程序的时候增加jmx配置,如下:

java -Djava.rmi.server.hostname=ttg12 -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false HelloWorld

注意:这种不需要验证的方式不安全!只用作测试,均不能用于外网可访问的生产环境!如何设置安全连接,请参考官方文档“Using Password Authentication"章节。

如果Java应用已经启动,且未在启动命令中启动JMX,那么可以通过诊断命令ManagementAgent.start来代理。具体使用方法和各类flags可使用jcmd <pid> help ManagementAgent.start查看。更多jcmd细节,参考官方文档
启动示例:

faceless@ttg12:~/tmp$ jcmd 26548 ManagementAgent.start jmxremote.host=ttg12 jmxremote.port=9999 jmxremote.rmi.port=9999 jmxremote.ssl=false jmxremote.authenticate=false
26548:
Command executed successfully

再多说一句,官方推荐尽量在启动应用的时候就开启JMX,因为JMX不会给应用带来任何负担,但却可以为后面的监控和问题定位带来极大的便利。著名的消息队列RocketMQ就是通过JMX提供监控和管理接口。

来源:Enable Options/Flags for JVM Troubleshooting第6点。

在VisualVM客户端增加JMX连接远程主机:

填入主机和端口号,勾选不使用ssl:

OK,现在除了Monitor之外,还可以监控线程和使用Sampler了。

Threads界面如下图:

Sampler界面如下图:

本文运行环境:
java:oracle jdk 8
server os:ubuntu 18.04
client os:macos 10.15.5

03-05 22:30