如何在 JVM 上激活 JMX 以使用 jconsole 进行访问?
12 回答
相关文档可以在这里找到:
http://java.sun.com/javase/6/docs/technotes/guides/management/agent.html
使用以下参数启动您的程序:
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9010
-Dcom.sun.management.jmxremote.rmi.port=9010
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
例如像这样:
java -Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=9010 \
-Dcom.sun.management.jmxremote.local.only=false \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false \
-jar Notepad.jar
-Dcom.sun.management.jmxremote.local.only=false
不一定需要,但没有它,它在 Ubuntu 上不起作用。错误将是这样的:
01 Oct 2008 2:16:22 PM sun.rmi.transport. customer .TCPTransport$AcceptLoop executeAcceptLoop
WARNING: RMI TCP Accept-0: accept loop for ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=37278] throws
java.io.IOException: The server sockets created using the LocalRMIServerSocketFactory only accept connections from clients running on the host where the RMI remote objects have been exported.
at sun.management.jmxremote.LocalRMIServerSocketFactory$1.accept(LocalRMIServerSocketFactory.java:89)
at sun.rmi.transport. customer .TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.java:387)
at sun.rmi.transport. customer .TCPTransport$AcceptLoop.run(TCPTransport.java:359)
at java.lang.Thread.run(Thread.java:636)
见http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6754672
还要小心-Dcom.sun.management.jmxremote.authenticate=false
哪个使任何人都可以访问,但是如果您只使用它来跟踪本地机器上的 JVM,那没关系。
更新:
在某些情况下,我无法访问服务器。如果我也设置了这个参数,这个问题就得到了修复:-Djava.rmi.server.hostname=127.0.0.1
在 Docker 容器中运行会带来一系列额外的连接问题,因此希望这对某人有所帮助。我最终需要添加以下选项,我将在下面解释:
-Dcom.sun.management.jmxremote=true
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Djava.rmi.server.hostname=${DOCKER_HOST_IP}
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.rmi.port=9998
DOCKER_HOST_IP
与在本地使用 jconsole 不同,您必须通告与您可能在容器中看到的不同的 IP。您需要替换${DOCKER_HOST_IP}
为 Docker 主机的外部可解析 IP(DNS 名称)。
JMX 远程和 RMI 端口
看起来 JMX 还需要访问远程管理接口 ( jstat ),该接口在仲裁连接时使用不同的端口来传输一些数据。我没有看到任何明显的jconsole
设置这个值的地方。在链接的文章中,过程是:
jconsole
在启用日志记录的情况下尝试连接- 失败
- 找出
jconsole
试图使用的端口 - 根据需要使用
iptables
/firewall
规则以允许该端口连接
虽然可行,但它肯定不是一个可自动化的解决方案。我选择从 jconsole 升级到VisualVM,因为它让您明确指定jstatd
正在运行的端口。在 VisualVM 中,添加一个新的远程主机并使用与上面指定的值相关的值对其进行更新:
然后右键单击新的远程主机连接并Add JMX Connection...
不要忘记选中 的复选框Do not require SSL connection
。希望这应该允许您连接。
请注意,最新版本的 Java 6 允许 jconsole 将自身附加到正在运行的进程,即使它已在没有 JMX 咒语的情况下启动。
如果您可以使用它,还可以考虑使用 jvisualvm,因为它提供了有关正在运行的进程的大量信息,包括分析器。
我正在使用 WAS ND 7.0
我的 JVM 需要在 JConsole 中监控以下所有参数
-Djavax.management.builder.initial=
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=8855
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
在 Linux 上,我使用了以下参数:
-Djavax.management.builder.initial=
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9010
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
我还进行了编辑/etc/hosts
,以便主机名解析为主机地址(192.168.0.x)而不是环回地址(127.0.0.1)
以下选项对我有用:
-Dcom.sun.management.jmxremote=true
-Dcom.sun.management.jmxremote.port=9010
-Dcom.sun.management.jmxremote.rmi.port=9010
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Djava.rmi.server.hostname={host name}
并且记得在服务器中打开9010端口
sudo ufw allow 9010/udp
sudo ufw allow 9010/tcp
sudo ufw reload
连同以下命令行参数,
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
有时在 linux 服务器中,imx 连接没有成功。那是因为,在云 linux 主机中,在 /etc/hosts 中,主机名解析为主机地址。
修复它的最好方法是,从网络中的其他机器 ping 特定的 linux 服务器,并在
-Djava.rmi.server.hostname=IP address that obtained when you ping that linux server.
但永远不要依赖使用 ifconfig.me 从 linux 服务器获得的 ipaddress。您在那里获得的 ip 被屏蔽,它存在于主机文件中。
使用以下命令行参数运行您的 java 应用程序:
-Dcom.sun.management.jmxremote.port=8855
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
如果您不想在 jmx 主机上设置数字证书,请务必使用-Dcom.sun.management.jmxremote.ssl=false参数。
如果您在 IP 地址为192.168.0.1的机器上启动应用程序,请打开jconsole,将192.168.0.1:8855放在Remote Process字段中,然后单击Connect。
第 1 步:使用以下参数运行应用程序。
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
以上参数将应用程序绑定到端口 9999。
第 2 步:通过在命令提示符或终端中执行命令 jconsole 来启动 jconsole。
选择“远程进程:”并输入网址为 {IP_Address}:9999,然后单击“连接”按钮以连接到远程应用程序。
您可以参考此链接以获取完整的应用程序。
使用远程进程选项运行本地进程 JCONSOLE
要在本地运行,这对我有用 -
我在我的vm args 中添加了这个 -
-Dcom.sun.management.jmxremote=true
-Dcom.sun.management.jmxremote.port=6001
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Djava.rmi.server.hostname=localhost
-Dcom.sun.management.jmxremote.rmi.port=6001
- 我通过Intellij终端打开了JConsole
- 它在本地向我显示所有 PID 为灰色
- 所以我选择了远程进程并使用主机登录 - localhost:6001
- 保留空的用户名和密码
- 然后点击连接
- 确保没有其他进程在端口 6001 上运行。您也可以使用其他端口。
首先,您需要检查您的 java 进程是否已经使用 JMX 参数运行。做这个:
ps -ef | grep java
检查您需要监控的 java 进程。如果你可以看到 jmx rmi 参数Djmx.rmi.registry.port=xxxx然后使用你的 java visualvm 中提到的端口在 jmx 连接下远程连接它。
如果它没有通过 jmx rmi 端口运行,那么您需要使用以下参数运行您的 java 进程:
-Djmx.rmi.registry.port=1234 -Djmx.rmi.port=1235 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false
注意:端口号取决于您的选择。
现在您可以将此端口用于 jmx 连接。这里是端口1234
。
我遇到了这个确切的问题,并创建了一个 GitHub 项目来测试和找出正确的设置。
它包含一个Dockerfile
支持脚本的工作,以及一个简单docker-compose.yml
的快速测试。