如何激活JVM上的JMX以使用jconsole进行访问?
-
它是允许的,实际上只是对我的提醒,因为我总是忘记从哪里复制参数,现在我知道在哪里找到它了:-)
-
Stack Exchange一直明确鼓励用户回答自己的问题,请参见此处:stackoverflow.com/help/self-answer
-
我不止一次地在SO中搜索某些内容,并发现一个问题……由我自己回答。我也问了其中一个。这就是为什么最好输入自己的答案。此外,请考虑可能遇到问题的所有其他人,如果回答您的问题,也会对他们有所帮助。
-
Java 8的更新文档在这里
-
@Mauren:您能为自己回答的封闭问题提供参考吗?在Meta上可能值得讨论。
-
@kevinarpe对不起。这已经很久了,我无法再为您提供链接和内容。
-
问题应该提到,当尝试启动CPU采样时jvisualvm告诉您"无法建立与目标应用程序的JMX连接"时,您可能有完全相同的问题。
相关文档可以在这里找到:
http://java.sun.com/javase/6/docs/technotes/guides/management/agent.html
使用以下参数启动程序:
1 |
–Dcom.sun.management.jmxremote |
例如这样的:
1 |
java –Dcom.sun.management.jmxremote \\ |
-Dcom.sun.management.jmxremote.local.only=false不一定是必需的
但是如果没有它,它将无法在Ubuntu上运行。错误可能是这样的
这个:
1 |
01 Oct 2008 2:16:22 PM sun.rmi.transport. customer .TCPTransport$AcceptLoop executeAcceptLoop |
参见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选择:我觉得com.sun.management.jmxremote的默认值为true很奇怪。 (感谢Sun!)要特别清楚,尤其是对于那些不太熟悉JMX nob的人,我使用:com.sun.management.jmxremote=true Ref:docs.oracle.com/javase/8/docs/technotes/guides/management/
-
" -Djava.rmi.server.hostname"对我来说就像是一种魅力!
-
使用Ubuntu 14.04,一切都可以直接使用。搬到Debian jessie,我不得不做这个答案中解释的所有事情
-
如果您尝试通过SSH隧道将主机名连接到远程服务器,则将主机名设置为localhost非常重要。
-
仅当我禁用服务器上的防火墙时,此方法才有效。我当然在此示例中打开了端口9010 / tcp,我也尝试添加Dcom.sun.management.jmxremote.rmi.port=9011并在防火墙中打开-仍然无法与正在启动的防火墙连接。有什么想法吗?我错过了什么吗?
-
@Carmageddon -Dcom.sun.management.jmxremote.rmi.port=[…]与-Djava.rmi.server.hostname=[…]结合使用应该有效。如果没有这些,我会遇到类似的问题,因此请确保您的客户端确实可以访问您为.rmi.port配置的端口,并且对于配置的.hostname相同!如果没有明确定义后者,则Java将假定某些IP,因为它是服务器的主要接口,但仍可能在防火墙中被阻止。如果没有端口,则假定为随机端口。您可以使用Wireshark或Process Monitor调试客户端/服务器的连接。
-
java.rmi.server.hostname此属性的值表示主机名字符串,该主机名字符串应与本地创建的远程对象的远程存根相关联,以便允许客户端调用远程对象上的方法。此属性的默认值是本地主机的IP地址,格式为"点分四进制"。 docs.oracle.com/javase/8/docs/technotes/guides/rmi/
-
如果您已经可以使用ssh访问服务器,则无需弄乱防火墙,只需创建一个网桥:ssh -g -L :localhost: @。示例:ssh -g -L 9523:localhost:9523 my-linux-account@5.23.56.78,然后转到jvisualvm,并将JMX连接添加为localhost:9523。不要忘记在远程服务器中添加:-Djava.rmi.server.hostname=127.0.0.1,因为没有它,它将无法工作。
在Docker容器中运行会给连接带来一系列其他问题,因此希望这对某人有所帮助。我最终需要添加以下我将在下面解释的选项:
1 |
–Dcom.sun.management.jmxremote=true |
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…
不要忘记选中Do not require SSL connection的复选框。希望这应该允许您连接。
-
在通过SSH隧道JMX / RMI的情况下,-Djava.rmi.server.hostname=localhost -Dcom.sun.management.jmxremote.rmi.port=[…]也是关键。 否则,将使用服务器的public / main / … IP通过一些随机端口访问远程对象,这些端口无法轻松转发。
-
我可以确认您确实需要使用容器IP的外部。 例如,它不适用于-Djava.rmi.server.hostname=0.0.0.0
-
我不需要在任何地方使用DOCKER_HOST_IP-我只是使用localhost并在运行docker映像时转发了端口:-p 9998:9998, -p 9999:9999等。
请注意,最新版本的Java 6允许jconsole将自身附加到正在运行的进程,即使在没有JMX声明的情况下启动它也是如此。
如果您可以使用,请考虑使用jvisualvm,因为它提供了有关正在运行的进程(包括探查器)的大量信息。
-
仅当您在与要监视的JVM相同的主机上运行jconsole时,此方法才有效。
-
@ Thorbjorn如果我启动不带任何参数的Java程序并尝试与jconsole连接,我会在列表中的程序中看到它,但是当我尝试连接它时失败。我认为是因为缺少SSL证书。我只是想看一下演示,因此我不得不使用user3013578答案中指定的参数,并且对我有用(JDK 1.7,Windows 8.1、64位)。
-
Attach API要求jconsole具有与某些平台上启动的程序相同的32/64位JVM。
-
是否可以禁用此行为?
我正在使用WAS ND 7.0
我的JVM需要在JConsole中监视以下所有参数
1 |
–Djavax.management.builder.initial= |
-
是的,您的答案对我有用(JDK 1.7,Windows 8.1 64位)
在Linux上,我使用了以下参数:
1 |
–Djavax.management.builder.initial= |
并且我还编辑了/etc/hosts,以便主机名解析为主机地址(192.168.0.x)而不是回送地址(127.0.0.1)
以及以下命令行参数,
1 |
–Dcom.sun.management.jmxremote.port=9999 |
有时,在Linux服务器中,imx连接不会成功。这是因为,在cloud linux主机中,在/ etc / hosts中,以便主机名解析为主机地址。
修复此问题的最佳方法是,从网络中的其他计算机ping特定的linux服务器,并在
1 |
–Djava.rmi.server.hostname=IP address that obtained when you ping that linux server. |
但是永远不要依赖您使用ifconfig.me从linux服务器获得的ipaddress。您到达那里的IP被屏蔽了一个存在于主机文件中的IP。
使用以下命令行参数运行Java应用程序:
1 |
–Dcom.sun.management.jmxremote.port=8855 |
如果您不想在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应该显示错误,还是只是悄无声息地无法连接?
以下选项对我有用:
1 |
–Dcom.sun.management.jmxremote=true |
并记得在服务器上打开9010端口
1 |
sudo ufw allow 9010/udp |
-
谢谢 ! 我错过了它。 现在可以使用
步骤1:使用以下参数运行应用程序。
1 |
–Dcom.sun.management.jmxremote.port=9999 |
上面的参数将应用程序绑定到端口9999。
步骤2:通过在命令提示符或终端中执行命令jconsole启动jconsole。
选择"远程进程:",然后输入网址为{IP_Address}:9999,然后单击"连接"按钮以连接到远程应用程序。
您可以参考此链接以获取完整的应用程序。
首先,您需要检查Java进程是否已经使用JMX参数运行。做这个:
1 |
ps –ef | grep java |
检查您需要监视的Java进程。如果可以看到jmx rmi参数Djmx.rmi.registry.port = xxxx,请使用Java visualvm中此处提到的端口在jmx连接下远程连接它。
如果它不是通过jmx rmi端口运行的,那么您需要使用以下提到的参数运行Java进程:
1 |
–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没有为我显示任何内容
我遇到了这个确切的问题,并创建了一个GitHub项目来测试和确定正确的设置。
它包含带有支持脚本的有效Dockerfile和用于快速测试的简单docker-compose.yml。