前言
本文是jvisualVM + Jstatd 组合方式远程监控服务器JVM进程情况。使用这种方式主要原因是:发现远程服务器两个JVM进程内存消耗有些多,所以需要进行监控以获得更多的信息。使用这种方式又考虑到:不能使用jvisualVM +JMX方式,这是因为JMX方式需要异常的JVM进程在启动时加入JVM参数,从而达到监控的目的,然而现在的情况是异常的JVM并没有加,为了保护现场,不能关闭JVM、加入参数再启动。所以决定使用jvisualVM + Jstatd 方式进行远程监控。在远程服务器上Jstatd 会开启用于监控JVM的进程,同时可以与远程监控工具(这里是jvisualVM )通信,不需要在异常的JVM上做手脚,从而保护了现场。
步骤
以下步骤亲测可行
新建文件,并编辑jstatd-all.policy
(任意文件位置)
vim /opt/jstatd-all.policy
复制以下内容到 jstatd-all.policy
文件中,注意:系统中需存在此JAVA_HOME
变量,并指向jdk根目录。
grant codeBase "file:${JAVA_HOME}lib/tools.jar" {
permission java.security.AllPermission;
};
保存,退出
运行命令jstatd -J-Djava.security.policy=/opt/jstatd.all.policy
后,报错,提示没有ignoreSubClasses
写的权限。如下所示:
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:886)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
at java.lang.System.setProperty(System.java:794)
at sun.tools.jstatd.Jstatd.main(Jstatd.java:139)
没权限,就要授权
vim ${JAVA_HOME}/jre/lib/security/java.policy
在grant块(就一堆permission关键字那块),新增如下
permission java.util.PropertyPermission "java.rmi.server.ignoreSubClasses", "write";
保存,退出。
继续 jstatd -J-Djava.security.policy=/opt/jstatd.all.policy
运行,发现还是报错没有其他权限,那么需要重复以上步骤,缺什么权限,就补什么权限,直到不报错为止。
此次,因为我需要授权的东西太多了,所以就把需要的权限全部开启,这也是无奈的办法。这种开启全部权限总觉得有些不安全,如果有的伙伴能够想出其他好办法,希望能够指点下。
那就授予全部权限:在 java.policy
授权如下:
vim ${JAVA_HOME}/jre/lib/security/java.policy
permission java.io.FilePermission "/tmp/-", "read";
permission java.util.PropertyPermission "*", "read";
permission java.net.SocketPermission "*", "connect,resolve,accept,listen";
permission java.util.PropertyPermission "*", "read";
保存,退出。
使用命令
jstatd -J-Djava.security.policy=/opt/jstatd.all.policy -p 12345 -J-Djava.rmi.server.logCalls=true -J-Djava.rmi.server.hostname=192.168.1.6
这里 新增开启日志输出、端口主机地址 选项:
-J-Djava.rmi.server.logCalls=true
,开启日志主要为了排除异常。
-p 12345
端口一会连接会用到
-J-Djava.rmi.server.hostname=192.168.1.6
远程服务器地址
到这里,我的就能够正常从jvisualVM
访问到jstatd
了,如果你的不能连接,或者有不一样行为的地方,一定要打开日志输出排查,这样是效率最高的。
接下来jvisualVM
连接jstatd
等待几秒后,刷新出了JVM进程