远程JMX连接

我试图打开一个JMX连接到运行在远程机器上的Java应用程序。

应用程序JVMconfiguration有以下选项:

  • com.sun.management.jmxremote
  • com.sun.management.jmxremote.port = 1088
  • com.sun.management.jmxremote.authenticate = FALSE
  • com.sun.management.jmxremote.ssl = FALSE

我可以使用jconsole或jvisualvm使用localhost:1088进行连接。 但是我无法使用远程机器上的xxx.xxx.xxx.xxx:1088进行连接。

服务器之间或OS上没有防火墙。 但为了消除这种可能性,我telnet xxx.xxx.xxx.xxx 1088 ,我认为它连接,因为控制台屏幕变成空白。

两台服务器都是Windows Server 2008 x64。 试过用64位JVM和32位,都没有工作。

如果在Linux上,问题将是本地主机是回环接口 ,您需要应用程序绑定到您的networking接口

您可以使用netstat来确认它没有绑定到预期的networking接口。

您可以通过调用带有系统参数java.rmi.server.hostname="YOUR_IP"的程序来完成这项工作,无论是作为环境variables还是使用

 java -Djava.rmi.server.hostname=YOUR_IP YOUR_APP 

我花了一天多时间试图让JMX从localhost之外工作。 SUN / Oracle似乎没有提供一个很好的文档。

确保以下命令返回一个真实的IP或HOSTNAME。 如果它返回类似127.0.0.1,127.0.1.1或localhost,则它将不起作用,您将不得不更新/etc/hosts文件。

 hostname -i 

这是从外部启用JMX所需的命令

 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=1100 -Djava.rmi.server.hostname=myserver.example.com 

按照您的假设,myserver.example.com必须匹配hostname -i返回的内容。

显然,你需要确保防火墙不会阻止你,但我几乎可以肯定,这不是你的问题,问题是没有logging的最后一个参数。

http://blogs.oracle.com/jmxetc/entry/troubleshooting_connection_problems_in_jconsole

如果您尝试访问位于NAT后面的服务器,则最有可能必须使用该选项启动服务器

 -Djava.rmi.server.hostname=<public/NAT address> 

以便发送给客户端的RMI存根包含服务器的公共地址,以允许来自外部的客户端到达。

在使用Tomcat和Java 8进行testing时,除了为JMX指定的端口之外,JVM还打开了一个临时端口。 下面的代码固定了我; 如果你的JMX客户端(例如VisualVM没有连接,

 -Dcom.sun.management.jmxremote.port=8989 -Dcom.sun.management.jmxremote.rmi.port=8989 

另请参阅configurationJMX时为什么Java会打开3个端口?

它接近你的结局报价来得太早。 它应该在最后一个参数之后。

这个窍门对我有用。

我注意到一些有趣的事情:当我使用下面的命令行启动我的应用程序时:

 java -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false 

如果我尝试使用jconsole从远程计算机连接到此端口,TCP连接成功,则在远程jconsole和部署了MBean的本地jmx代理之间交换一些数据,然后jconsole显示连接错误消息。 我执行了wireshark捕获,它显示来自代理和jconsole的数据交换。

因此,这不是一个networking问题,如果我执行一个netstat -an有或没有java.rmi.server.hostname系统属性,我有以下的绑定:

  TCP 0.0.0.0:9999 0.0.0.0:0 LISTENING TCP [::]:9999 [::]:0 LISTENING 

这意味着在这两种情况下,在端口9999上创build的套接字都接受来自任何地址上的任何主机的连接。

我认为这个系统属性的内容在连接的某个地方使用,并与代理与jconsole通信所使用的实际IP地址进行比较。 如果这些地址不匹配,则连接失败。

从同一台主机使用jconsole进行连接时,我没有遇到这个问题,只能从实际的物理远程主机进行连接。 所以,我想这个检查只在连接来自“外部”时才能完成。

非常感谢,它的工作原理是这样的:

java -Djava.rmi.server.hostname = xxx.xxx.xxx.xxx -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.ssl = false -Dcom.sun.management.jmxremote.authenticate = false – Dcom.sun.management.jmxremote.port = 25000 -jar myjar .jar

对我来说工作的东西是设置/ etc / hosts指向主机名到IP而不是回送接口,并重新启动我的应用程序。

猫/ etc / hosts

 127.0.0.1 localhost.localdomain localhost 192.168.0.1 myservername 

这是我的configuration:

 -Dcom.sun.management.jmxremote.port=1617 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false 

我有同样的问题,我将任何匹配本地主机名称的主机名更改为0.0.0.0,这似乎工作后,我这样做。

尝试使用高于3000的端口。