Ich versuche, eine JMX-Verbindung zu einer Java-Anwendung herzustellen, die auf einem Remotecomputer ausgeführt wird.
Die Anwendungs-JVM wird mit den folgenden Optionen konfiguriert:
- com.sun.management.jmxremote
- com.sun.management.jmxremote.port = 1088
- com.sun.management.jmxremote.authenticate = false
- com.sun.management.jmxremote.ssl = false
Ich kann eine Verbindung localhost:1088
mit jconsole oder jvisualvm herstellen. Ich kann jedoch keine Verbindung xxx.xxx.xxx.xxx:1088
von einem Remotecomputer aus herstellen.
Es gibt keine Firewall zwischen den Servern oder auf dem Betriebssystem. Aber um diese Möglichkeit auszuschließen, telnet xxx.xxx.xxx.xxx 1088
denke ich, dass es eine Verbindung herstellt, wenn der Konsolenbildschirm leer wird.
Beide Server sind Windows Server 2008 x64. Versucht mit 64-Bit-JVM und 32-Bit, beide funktionieren nicht.
Antworten:
Wäre es unter Linux gewesen, wäre das Problem, dass localhost die Loopback-Schnittstelle ist. Sie müssen eine Anwendung verwenden, um sich an Ihre Netzwerkschnittstelle zu binden .
Mit netstat können Sie bestätigen, dass es nicht an die erwartete Netzwerkschnittstelle gebunden ist.
Sie können dies zum Laufen bringen, indem Sie das Programm mit dem Systemparameter
java.rmi.server.hostname="YOUR_IP"
entweder als Umgebungsvariable oder mit aufrufenquelle
hostname -i
, siehe stackoverflow.com/a/11654322/99834 für Details.Ich habe mehr als einen Tag damit verbracht, JMX dazu zu bringen, von außerhalb von localhost zu arbeiten. Es scheint, dass SUN / Oracle diesbezüglich keine gute Dokumentation geliefert hat.
Stellen Sie sicher, dass der folgende Befehl eine echte IP oder einen echten Hostnamen zurückgibt. Wenn es etwas wie 127.0.0.1, 127.0.1.1 oder localhost zurückgibt, funktioniert es nicht und Sie müssen die
/etc/hosts
Datei aktualisieren .Hier ist der Befehl, der benötigt wird, um JMX auch von außen zu aktivieren
Wo, wie Sie angenommen haben, muss myserver.example.com mit den zurückgegebenen Ergebnissen übereinstimmen
hostname -i
.Natürlich müssen Sie sicher sein, dass die Firewall Sie nicht blockiert, aber ich bin mir fast sicher, dass dies nicht Ihr Problem ist. Das Problem ist der letzte Parameter, der nicht dokumentiert ist.
quelle
java.rmi.server.hostname=<Public DNS name from AWS EC2 console for the instance>
. Hoffe das hilft jemandem.Bei meinen Tests mit Tomcat und Java 8 hat die JVM zusätzlich zu dem für JMX angegebenen einen kurzlebigen Port geöffnet. Der folgende Code hat mich repariert; Probieren Sie es aus, wenn Sie Probleme haben, bei denen Ihr JMX-Client keine Verbindung herstellt (z. B. VisualVM) .
Siehe auch Warum Java 3 Ports öffnet, wenn JMX konfiguriert ist?
quelle
http://blogs.oracle.com/jmxetc/entry/troubleshooter_connection_problems_in_jconsole
Wenn Sie versuchen, auf einen Server zuzugreifen, der sich hinter einem NAT befindet, müssen Sie Ihren Server höchstwahrscheinlich mit dieser Option starten
Damit enthalten die an den Client gesendeten RMI-Stubs die öffentliche Adresse des Servers, sodass die Clients von außen darauf zugreifen können.
quelle
Es scheint, dass Ihr Endzitat zu früh kommt. Es sollte nach dem letzten Parameter sein.
Dieser Trick hat bei mir funktioniert.
Mir ist etwas Interessantes aufgefallen: Wenn ich meine Anwendung über die folgende Befehlszeile starte:
Wenn ich versuche, mit jconsole von einem Remotecomputer aus eine Verbindung zu diesem Port herzustellen, ist die TCP-Verbindung erfolgreich. Einige Daten werden zwischen der Remote-jconsole und dem lokalen jmx-Agenten ausgetauscht, auf dem meine MBean bereitgestellt wird. Anschließend zeigt jconsole eine Verbindungsfehlermeldung an. Ich habe eine Wireshark-Erfassung durchgeführt, die den Datenaustausch sowohl vom Agenten als auch von der Jconsole zeigt.
Daher ist dies kein Netzwerkproblem. Wenn ich ein netstat -an mit oder ohne Systemeigenschaft java.rmi.server.hostname ausführe, habe ich die folgenden Bindungen:
Dies bedeutet, dass in beiden Fällen der an Port 9999 erstellte Socket Verbindungen von einem beliebigen Host an einer beliebigen Adresse akzeptiert.
Ich denke, der Inhalt dieser Systemeigenschaft wird irgendwo bei der Verbindung verwendet und mit der tatsächlichen IP-Adresse verglichen, die der Agent für die Kommunikation mit jconsole verwendet. Und wenn diese Adressen nicht übereinstimmen, schlägt die Verbindung fehl.
Ich hatte dieses Problem nicht, als ich mit jconsole vom selben Host aus eine Verbindung herstellte, sondern nur von echten physischen Remote-Hosts. Ich nehme also an, dass diese Überprüfung nur durchgeführt wird, wenn die Verbindung von "außen" kommt.
quelle
Für mich funktionierte es, / etc / hosts so einzustellen, dass der Hostname auf die IP und nicht auf die Loopback-Schnittstelle verweist, und dann meine Anwendung neu zu starten.
Katze / etc / Hosts
Dies ist meine Konfiguration:
quelle
Vielen Dank, es funktioniert so:
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
quelle
Ich weiß, dass dieser Thread ziemlich alt ist, aber es gibt eine zusätzliche Option, die sehr hilfreich sein wird. Siehe hier: https://realjenius.com/2012/11/21/java7-jmx-tunneling-freedom/
-Dcom.sun.management.jmxremote.rmi.port=1099
quelle
Ich habe das gleiche Problem und ändere jeden Hostnamen, der mit dem lokalen Hostnamen übereinstimmt, in 0.0.0.0. Danach scheint es zu funktionieren.
quelle
Um JMX Remote zu aktivieren, übergeben Sie die folgenden VM-Parameter zusammen mit JAVA Command.
quelle
Versuchen Sie dies, ich habe getestet, um auf JMX im Docker-Container zuzugreifen
Dann
$ jconsole localhost: 16000
quelle
Versuchen Sie, Ports höher als 3000 zu verwenden.
quelle