使用jvm工具排查系统问题

java-jvm-tool

Jstatd 远程连接(推荐)

不用重启项目

远程机配置

[demo@localhost jvmtest]$ vi jstatd.all.policy

# 内容
grant codebase "file:/home/demo/jdk1.8.0_171/lib/tools.jar" {
permission java.security.AllPermission;
};

#IP为远程机外网IP(必须配置ip地址)
[demo@localhost jvmtest]$ nohup jstatd -J-Djava.security.policy=jstatd.all.policy -J-Djava.rmi.server.hostname=172.16.29.61 -p 1099 -J-Djava.rmi.server.logCalls=true &
[1] 203089
[demo@localhost jvmtest]$ nohup: 忽略输入并把输出追加到"nohup.out"


       [demo@localhost jvmtest]$

       [demo@localhost jvmtest]$ tail -f nohup.out

       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)

          十二月 19, 2023 2:28:49 下午 sun.rmi.server.UnicastServerRef logCall

          较详细: RMI TCP Connection(1)-127.0.0.1: [127.0.0.1: sun.rmi.registry.RegistryImpl[0:0:0, 0]: void rebind(java.lang.String, java.rmi.Remote)]

          十二月 19, 2023 2:28:50 下午 sun.rmi.server.UnicastServerRef logCall

          较详细: RMI TCP Connection(2)-172.16.29.61: [172.16.29.61: sun.rmi.transport.DGCImpl[0:0:0, 2]: java.rmi.dgc.Lease dirty(java.rmi.server.ObjID[], long, java.rmi.dgc.Lease)]

# 记得防火墙开端口或者直接关闭防火墙

           [root@localhost ~]# firewall-cmd --zone=public --add-port=1099/tcp --permanent

            [root@localhost ~]# firewall-cmd --reload

客户端连接

在配置好环境变量的前提下,直接在cmd下执行 jvisualvm命令。
客户端运行jvisualvm visualvm中添加远程机

选中添加的远程机,右击,点击【添加 jstatd 连接】,可以设置端口以及刷新时间。
jstatd端口配置 配置详情 最终结果

JMX 连接

服务端启动配置

-Dcom.sun.management.jmxremote.port=8999  \
-Dcom.sun.management.jmxremote.rmi.port=8999 \
-Dcom.sun.management.jmxremote.ssl=false  \
-Dcom.sun.management.jmxremote.authenticate=false \
-Djava.rmi.server.hostname=172.16.29.61 \

客户端连接

jvisualvm

首先,右击【远程】,点击【添加远程主机】

然后,右击添加的主机,点击【添加 JMX 连接】,输入对应端口号。
添加JMX连接

jconsole

在配置好环境变量的前提下,直接在cmd下执行 jconsole命令。
新建连接 可检测死锁

补充

linux shell 参数换行(标准说法:续行)

\Enter,反斜杠后面紧跟回车,表示下一行是当前行的续行。(For Windows, use the carat (^) instead of the backslash (\) to break up a long command into multiple lines)

nohup java -jar -XX:MetaspaceSize=1024m \
-XX:MaxMetaspaceSize=2048m  \
-Dcom.sun.management.jmxremote.port=8999  \
-Dcom.sun.management.jmxremote.rmi.port=8999 \
-Dcom.sun.management.jmxremote.ssl=false  \
-Dcom.sun.management.jmxremote.authenticate=false \
-Djava.rmi.server.hostname=172.16.29.61 \
 -Dlog4j2.formatMsgNoLookups=true \
 ${APP_NAME} --server.port=8082 >> logs/8082.log 2>&1 &

问题

java.security.AccessControlException: access denied

可将文件 jstatd.all.policy 文件中的${JAVA_HOME}写成绝对路径即可。

参考

Monitoring and Management Using JMX Technology - Java SE Monitoring and Management Guide (oracle.com)

JDK Tools and Utilities

Monitoring and Management Using JMX Technology

Monitoring and Management Guide

Enabling remote JMX with password authentication only (apache.org)

JMX 入门(三)认证加密_jmx 加密-CSDN 博客

为 JMX JConsole 设置用户名密码登录_jconsole 连接本机默认用户名密码-CSDN 博客

选项 2:在不使用 SSL 的情况下设置 JMX 以进行客户机认证 - IBM 文档