如何激活JMX在我的JVM访问jconsole?

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

336534 次浏览

相关文件可在此找到:

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上工作。误差是这样的 : < / p >

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

< p > 还要注意-Dcom.sun.management.jmxremote.authenticate=false哪个 任何人都可以访问,但是如果您只使用它来跟踪JVM

更新:

在某些情况下,我无法连接到服务器。如果我也设置了这个参数:-Djava.rmi.server.hostname=127.0.0.1,这个问题就被修复了

注意,Java 6的最新版本允许jconsole将自己附加到正在运行的进程上,即使在没有JMX咒语的情况下启动了进程。

如果可以使用jvisualvm,也可以考虑jvisualvm,因为它提供了大量关于运行进程的信息,包括一个分析器。

使用以下命令行参数运行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,然后单击连接

我使用的是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)

在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远程&RMI端口

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

  • 尝试从jconsole连接并启用日志记录
  • 失败
  • 找出jconsole试图使用的端口
  • 必要时使用iptables/firewall规则来允许该端口连接

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

添加远程主机

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

Add JMX Connection

不要忘记勾选Do not require SSL connection的复选框。希望这能让你们建立联系。

我有这个确切的问题,和创建了一个GitHub项目,用于测试和确定正确的设置

它包含一个工作的Dockerfile和支持脚本,以及一个简单的docker-compose.yml用于快速测试。

连同下面的命令行参数,

-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服务器,并使用该主机IP地址

-Djava.rmi.server.hostname=IP address that obtained when you ping that linux server.

但是永远不要依赖于你从linux服务器上使用ifconfig.me获得的ipaddress。你得到的IP是掩码的,在主机文件中。

首先,您需要检查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

步骤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,然后单击连接按钮连接到远程应用程序。

你可以引用这个链接来获取完整的应用程序。

以下选项适合我:

-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

使用远程进程选项运行本地进程JCONSOLE

为了在本地运行,这对我来说是可行的

我在虚拟机 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上没有其他进程正在运行。您也可以使用其他端口。