如何在JVM上激活JMX以便使用jconsole访问?
如何在JVM上激活JMX以便使用jconsole访问?
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)
看看https://bugs.java.com/bugdatabase/view_bug?bug_id=6754672
还要小心-Dcom.sun.management.jmxremote.authenticate=false
,这使得任何人都可以访问,但如果你只是用它来跟踪本地机器上的JVM,那就没关系。
更新:
在某些情况下,我无法访问服务器。如果我设置了这个参数:-Djava.rmi.server.hostname=127.0.0.1
,问题就会解决。
com.sun.management.jmxremote
的默认值为 true
真的很奇怪。(感谢 Sun!)为了更加清晰明了,特别是对于那些不太熟悉 JMX 的人,我使用:com.sun.management.jmxremote=true
参考文献:http://docs.oracle.com/javase/8/docs/technotes/guides/management/agent.html - kevinarpeDcom.sun.management.jmxremote.rmi.port=9011
并在防火墙中打开 - 但仍无法连接。有什么想法吗?我有遗漏什么吗? - Carmageddon-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地址不同的IP地址。 您需要将${DOCKER_HOST_IP}
替换为Docker主机的可外部解析IP(DNS名称)。
JMX远程和RMI端口
看起来JMX还需要访问远程管理接口(jstat),该接口使用不同的端口传输一些数据以协调连接。 我没有在jconsole
中看到任何明显设置此值的地方。 在链接的文章中,步骤如下:
jconsole
连接jconsole
尝试使用的端口iptables
/ firewall
规则允许该端口连接虽然那样做可以实现目的,但它肯定不是一种可自动化的解决方案。我选择从jconsole升级到VisualVM,因为它允许您明确指定jstatd
正在运行的端口。在VisualVM中,添加一个新的远程主机,并使用与上述值相对应的值进行更新:
-Djava.rmi.server.hostname=localhost
-Dcom.sun.management.jmxremote.rmi.port=[...]
这两个参数也是在通过SSH隧道传输JMX/RMI时的关键。如果没有这些参数,远程对象将使用服务器的公共/主要/... IP和一些随机端口进行访问,这些端口不易被转发。 - Thorsten SchöningDOCKER_HOST_IP
- 我只是使用 localhost
并在运行 Docker 镜像时转发端口:-p 9998:9998, -p 9999:9999
等。 - Barneyjstatd
端口等同于-Dcom.sun.management.jmxremote.rmi.port
参数。虽然没有明确说明,但这会提高您的答案质量。谢谢! - Webchen -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
-Djava.rmi.server.hostname=IP address that obtained when you ping that linux server.
但是不要依赖使用ifconfig.me从Linux服务器获取的ip地址。您在那里获得的IP是掩码的,存在于主机文件中。
使用远程进程选项运行本地JCONSOLE
要在本地运行,请按照以下步骤操作:
我在我的vm参数中添加了以下内容:
-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
使用以下命令行参数运行您的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,然后单击连接。
jconsole
会显示错误,还是只是静默地无法连接? - amacleod步骤1: 使用以下参数运行应用程序。
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
以上参数将应用程序绑定到端口9999。
步骤2:通过在命令提示符或终端中执行jconsole命令来启动jconsole。
选择“远程进程:”,并将url输入为{IP_Address}:9999,然后单击“连接”按钮以连接到远程应用程序。
您可以参考此链接获取完整的应用程序。