【问题标题】:How to activate JMX on my JVM for access with jconsole?如何在我的 JVM 上激活 JMX 以使用 jconsole 进行访问?
【发布时间】:2010-10-25 19:21:41
【问题描述】:

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

【问题讨论】:

  • 它是允许的,实际上它只是对我的一个提醒,因为我总是忘记从哪里复制参数,现在我知道我在哪里找到它:-)
  • Stack Exchange 一直明确鼓励用户回答自己的问题,请参见此处:stackoverflow.com/help/self-answer
  • 不止一次我搜索了一些东西并找到了一个我自己回答的问题。其中一个也是我问的。这就是为什么最好把你自己的答案写进去。另外,想想其他可能遇到过你问题的人,如果你回答了你的问题,你也会帮助他们。
  • Java 8 的更新文档是here
  • @Mauren:你能提供一个你自己回答的封闭问题的参考吗?可能值得在 Meta 上讨论。

标签: java jvm monitoring 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

【讨论】:

  • Centos 现在也需要 -Dcom.sun.management.jmxremote.local.only=false
  • Nit pick:com.sun.management.jmxremote 的默认值为true,这对我来说很奇怪。 (谢谢 Sun!)为了超级清楚,特别是对于那些不太熟悉 JMX nobs 的人,我使用:com.sun.management.jmxremote=true Ref:docs.oracle.com/javase/8/docs/technotes/guides/management/…
  • "-Djava.rmi.server.hostname" 对我来说就像一个魅力!
  • 如果您尝试通过 SSH 隧道连接到远程服务器,将主机名设置为 localhost 非常重要,这是一种非常常见的情况。
  • 只有在我禁用服务器上的防火墙时才有效。我当然在这个例子中打开了端口 9010/tcp,我也尝试添加 Dcom.sun.management.jmxremote.rmi.port=9011 并在防火墙中打开 - 仍然无法连接防火墙正在启动。有什么想法吗?我错过了什么吗?
【解决方案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。您需要将 ${DOCKER_HOST_IP} 替换为 Docker 主机的外部可解析 IP(DNS 名称)。

JMX 远程和 RMI 端口

看起来 JMX 还需要访问远程管理接口 (jstat),uses a different port 在仲裁连接时传输一些数据。我没有在jconsole 中看到任何明显的设置这个值的地方。在链接的文章中,过程是:

  • 尝试从 jconsole 连接并启用日志记录
  • 失败
  • 找出jconsole尝试使用的端口
  • 根据需要使用iptables/firewall 规则以允许该端口连接

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

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

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

【讨论】:

  • -Djava.rmi.server.hostname=localhost -Dcom.sun.management.jmxremote.rmi.port=[...] 也是通过 SSH 建立 JMX/RMI 隧道的关键。没有这些,远程对象将使用 public/main/... 使用一些随机端口的服务器的 IP 访问,这些端口不能轻易转发。
  • 我可以确认您确实需要使用外部容器 IP。例如它不适用于-Djava.rmi.server.hostname=0.0.0.0
  • 我不需要在任何地方使用DOCKER_HOST_IP - 我只是使用localhost 并在运行docker 映像时转发端口:-p 9998:9998, -p 9999:9999 等。
  • 这也适用于我的 Docker-Java-Setup。更容易提到jstatd 端口等同于-Dcom.sun.management.jmxremote.rmi.port 参数。它没有明确说明,但它会提高你的答案的质量。谢谢!
【解决方案3】:

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

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

【讨论】:

  • 这仅适用于您在与您尝试监控的 JVM 相同的主机上运行 jconsole 的情况。
  • @ Thorbjorn 如果我在没有任何参数的情况下启动我的 java 程序并尝试连接 jconsole,我会在列表中的程序中看到,但是当我尝试连接时它会失败。我认为这是因为缺少 SSL 证书。我只是想看演示,因此我不得不使用 user3013578 在答案中指定的参数,它对我有用(JDK 1.7,Windows 8.1,64 位)。
  • 附加 API 要求 jconsole 与某些平台上的启动程序具有相同的 32/64 位 JVM。
  • 是否可以禁用此行为?
【解决方案4】:

我正在使用 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

【讨论】:

  • 是的,你的回答对我有用(JDK 1.7,windows 8.1 64 位)
【解决方案5】:

在 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)

【讨论】:

    【解决方案6】:

    以下选项对我有用:

    -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
    

    【讨论】:

      【解决方案7】:

      连同下面的命令行参数,

      -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.
      

      但永远不要依赖使用 ifconfig.me 从 linux 服务器获得的 IP 地址。您在那里获得的 ip 被屏蔽,它存在于主机文件中。

      【讨论】:

        【解决方案8】:

        使用以下命令行参数运行您的 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 放入远程进程字段,然后单击连接

        【讨论】:

        • 如果您忘记了-Dcom.sun.management.jmxremote.ssl=false,预期的行为是什么? jconsole 应该显示错误,还是只是悄悄地连接失败?
        【解决方案9】:

        第 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 并单击“连接”按钮以连接到远程应用程序。

        您可以参考此link 以获取完整的申请。

        【讨论】:

          【解决方案10】:

          使用远程进程选项运行本地进程 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
          
          I opened JConsole via Intellij Terminal
          It was showing me all PID's in grey in local
          So I selected remote process and logged in using host - localhost:6001
          Keep empty username & password
          Then click connect
          
          • 确保没有其他进程在端口 6001 上运行。您也可以使用其他端口。

          【讨论】:

            【解决方案11】:

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

            【讨论】:

            • 运行后是否可以看到 jmx 正在使用的端口 1234? sudo lsof -i:1234 没有为我显示任何内容
            【解决方案12】:

            我遇到了这个确切的问题,created a GitHub project for testing and figuring out the correct settings

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

            【讨论】:

              猜你喜欢
              • 2011-06-13
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多