如何在我的JVM上激活JMX以使用jconsole进行访问?

2022-08-31 05:35:21

如何在JVM上激活JMX以使用jconsole进行访问?


答案 1

相关文档可在此处找到:

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


答案 2

在 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 不同的 IP。您需要替换为 Docker 主机的外部可解析 IP(DNS 名称)。${DOCKER_HOST_IP}

JMX Remote & RMI Ports

看起来JMX还需要访问远程管理接口(jstat),该接口在仲裁连接时使用不同的端口来传输某些数据。我没有看到任何明显的设置此值的地方。在链接的文章中,该过程是:jconsole

  • 尝试在启用日志记录的情况下从 进行连接jconsole
  • 失败
  • 找出尝试使用的端口jconsole
  • 根据需要使用 / 规则以允许该端口连接iptablesfirewall

虽然这有效,但它肯定不是一个可自动化的解决方案。我选择从jconsole升级到VisualVM,因为它可以让你显式指定正在运行的端口。在 VisualVM 中,添加一个新的远程主机,并使用与上面指定的值相关的值对其进行更新:jstatd

Add Remote Host

然后右键单击新的远程主机连接,然后Add JMX Connection...

Add JMX Connection

不要忘记选中 的复选框。希望这应该可以让你连接。Do not require SSL connection


推荐