我正在尝试打开与远程计算机上运行的Java应用程序的JMX连接。
应用程序JVM配置有以下选项:
我可以使用jconsole或jvisualvm使用localhost:1088
进行连接。
但是我无法使用远程计算机上的xxx.xxx.xxx.xxx:1088
进行连接。
服务器之间或操作系统之间没有防火墙。但是为了消除这种可能性我telnet xxx.xxx.xxx.xxx 1088
并且我认为它连接起来,因为控制台屏幕变成空白。
这两台服务器都是Windows Server 2008 x64。尝试使用64位JVM和32位,都不起作用。
答案 0 :(得分:109)
如果它出现在Linux上,问题是 localhost是环回接口,您需要将应用程序绑定到网络接口。
您可以使用netstat确认它未绑定到预期的网络接口。
您可以通过使用系统参数java.rmi.server.hostname="YOUR_IP"
调用程序来作为环境变量或使用
java -Djava.rmi.server.hostname=YOUR_IP YOUR_APP
答案 1 :(得分:59)
我花了一天多的时间试图让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
返回的内容相匹配。
显然,您需要确保防火墙不会阻止您,但我几乎可以肯定这不是您的问题,问题是未记录的最后一个参数。
答案 2 :(得分:19)
在我使用Tomcat和Java 8进行的测试中,除了为JMX指定的端口之外,JVM还打开了一个临时端口。以下代码解释了我;如果您遇到JMX客户端(例如VisualVM未连接的问题),请尝试尝试。
-Dcom.sun.management.jmxremote.port=8989
-Dcom.sun.management.jmxremote.rmi.port=8989
答案 3 :(得分:12)
http://blogs.oracle.com/jmxetc/entry/troubleshooting_connection_problems_in_jconsole
如果您尝试访问NAT后面的服务器 - 您很可能必须使用选项启动服务器
-Djava.rmi.server.hostname=<public/NAT address>
以便发送到客户端的RMI存根包含服务器的公共地址,允许客户从外部访问它。
答案 4 :(得分:8)
它接近你的结尾报价来得太早了。它应该在最后一个参数之后。
这个技巧对我有用。
我注意到一些有趣的事情:当我使用以下命令行启动我的应用程序时:
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的数据交换。
因此,这不是网络问题,如果我使用或不使用java.rmi.server.hostname系统属性执行netstat -an,我有以下绑定:
TCP 0.0.0.0:9999 0.0.0.0:0 LISTENING
TCP [::]:9999 [::]:0 LISTENING
这意味着在两种情况下,在端口9999上创建的套接字都接受来自任何地址上任何主机的连接。
我认为此系统属性的内容在连接时使用,并与代理用于与jconsole通信的实际IP地址进行比较。如果这些地址不匹配,则连接失败。
使用jconsole从同一主机连接时,我没有遇到此问题,仅使用真实的物理远程主机。所以,我认为只有当连接来自“外部”时才会进行此检查。
答案 5 :(得分:5)
非常感谢,它的工作原理如下:
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
答案 6 :(得分:5)
对我有用的是将/ etc / hosts设置为将主机名指向ip,而不是指向loopback接口,而不是重启我的应用程序。
cat / etc / hosts
127.0.0.1 localhost.localdomain localhost
192.168.0.1 myservername
这是我的配置:
-Dcom.sun.management.jmxremote.port=1617
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
答案 7 :(得分:1)
我知道这个线程已经很老了,但是还有一个额外的选项可以极大地帮助您。看到这里:https://realjenius.com/2012/11/21/java7-jmx-tunneling-freedom/
-Dcom.sun.management.jmxremote.rmi.port=1099
答案 8 :(得分:0)
我有同样的问题,我将任何与本地主机名匹配的主机名更改为0.0.0.0,在我这样做之后似乎可以正常工作。
答案 9 :(得分:0)
要启用JMX remote,请将以下VM参数与JAVA Command一起传递。
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=453
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Djava.rmi.server.hostname=myDomain.in
答案 10 :(得分:0)
尝试一下,我测试了如何在docker容器中访问JMX
-Dcom.sun.management.jmxremote = true -Djava.rmi.server.hostname =本地主机 -Dcom.sun.management.jmxremote.port = 16000 -Dcom.sun.management.jmxremote.rmi.port = 16000 -Dcom.sun.management.jmxremote.authenticate = false -Dcom.sun.management.jmxremote.ssl = false
然后
$ jconsole localhost:16000
答案 11 :(得分:-10)
尝试使用高于3000的端口。