远程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的端口。