Wie kann ich JMX in einer JVM für den Zugriff mit Jconsole aktivieren?
Die entsprechende Dokumentation finden Sie hier:
http://Java.Sun.com/javase/6/docs/technotes/guides/management/agent.html
Starten Sie Ihr Programm mit folgenden Parametern:
-Dcom.Sun.management.jmxremote
-Dcom.Sun.management.jmxremote.port=9010
-Dcom.Sun.management.jmxremote.local.only=false
-Dcom.Sun.management.jmxremote.authenticate=false
-Dcom.Sun.management.jmxremote.ssl=false
Zum Beispiel so:
Java -Dcom.Sun.management.jmxremote \
-Dcom.Sun.management.jmxremote.port=9010 \
-Dcom.Sun.management.jmxremote.local.only=false \
-Dcom.Sun.management.jmxremote.authenticate=false \
-Dcom.Sun.management.jmxremote.ssl=false \
-jar Notepad.jar
-Dcom.Sun.management.jmxremote.local.only=false
ist nicht unbedingt erforderlich Aber ohne es funktioniert Ubuntu nicht. Der Fehler würde ungefähr so aussehen:
01 Oct 2008 2:16:22 PM Sun.rmi.transport. customer .TCPTransport$AcceptLoop executeAcceptLoop
WARNING: RMI TCP Accept-0: accept loop for ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=37278] throws
Java.io.IOException: The server sockets created using the LocalRMIServerSocketFactory only accept connections from clients running on the Host where the RMI remote objects have been exported.
at Sun.management.jmxremote.LocalRMIServerSocketFactory$1.accept(LocalRMIServerSocketFactory.Java:89)
at Sun.rmi.transport. customer .TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.Java:387)
at Sun.rmi.transport. customer .TCPTransport$AcceptLoop.run(TCPTransport.Java:359)
at Java.lang.Thread.run(Thread.Java:636)
siehe http://bugs.Sun.com/bugdatabase/view_bug.do?bug_id=6754672
Seien Sie auch vorsichtig mit -Dcom.Sun.management.jmxremote.authenticate=false
, wodurch Zugriff für jedermann möglich ist. Wenn Sie jedoch nur die JVM auf Ihres lokalen Computers verfolgen, spielt dies keine Rolle.
Update:
In einigen Fällen konnte ich den Server nicht erreichen. Dies wurde behoben, wenn ich auch diesen Parameter einstelle: -Djava.rmi.server.hostname=127.0.0.1
Das Laufen in einem Docker-Container führte zu einer ganzen Reihe zusätzlicher Probleme beim Verbindungsaufbau. Dies hilft hoffentlich jemandem. Am Ende musste ich die folgenden Optionen hinzufügen, die ich im Folgenden erklären werde:
-Dcom.Sun.management.jmxremote=true
-Dcom.Sun.management.jmxremote.local.only=false
-Dcom.Sun.management.jmxremote.authenticate=false
-Dcom.Sun.management.jmxremote.ssl=false
-Djava.rmi.server.hostname=${DOCKER_Host_IP}
-Dcom.Sun.management.jmxremote.port=9999
-Dcom.Sun.management.jmxremote.rmi.port=9998
DOCKER_Host_IP
Im Gegensatz zur lokalen Verwendung von jconsole müssen Sie eine andere IP-Adresse angeben, als Sie wahrscheinlich innerhalb des Containers sehen werden. Sie müssen ${DOCKER_Host_IP}
durch die extern auflösbare IP-Adresse (DNS-Name) Ihres Docker-Hosts ersetzen.
JMX Remote- und RMI-Ports
Es sieht so aus, als müsste JMX auch auf eine Remote-Management-Schnittstelle ( jstat ) zugreifen, die einen anderen Port verwendet , um einige Daten zu übertragen, wenn die Verbindung vermittelt wird. Ich habe in jconsole
nirgendwo etwas offensichtliches gesehen, um diesen Wert einzustellen. In dem verlinkten Artikel war der Prozess:
jconsole
mit aktivierter Protokollierungjconsole
verwendet hatiptables
/firewall
-Regeln, damit sich dieser Port verbinden kannDas funktioniert zwar, ist aber sicherlich keine automatisierbare Lösung. Ich habe mich für ein Upgrade von jconsole auf VisualVM entschieden, da Sie hier explizit den Port angeben können, auf dem jstatd
ausgeführt wird. Fügen Sie in VisualVM einen neuen Remote-Host hinzu und aktualisieren Sie ihn mit Werten, die mit den oben angegebenen übereinstimmen:
Klicken Sie dann mit der rechten Maustaste auf die neue Remote-Host-Verbindung und Add JMX Connection...
.
Vergessen Sie nicht, das Kontrollkästchen für Do not require SSL connection
zu aktivieren. Hoffentlich sollte das eine Verbindung ermöglichen.
Hinweis: Java 6 in der neuesten Version ermöglicht es jconsole, sich an einen laufenden Prozess anzuhängen, auch wenn es ohne JMX-Beschwörungszeichen gestartet wurde.
Wenn dies für Sie verfügbar ist, sollten Sie auch jvisualvm in Betracht ziehen, da es eine Fülle von Informationen über laufende Prozesse enthält, einschließlich eines Profilers.
Ich verwende WAS ND 7.0
Meine JVM benötigt alle folgenden Argumente, um in JConsole überwacht zu werden
-Djavax.management.builder.initial=
-Dcom.Sun.management.jmxremote
-Dcom.Sun.management.jmxremote.port=8855
-Dcom.Sun.management.jmxremote.authenticate=false
-Dcom.Sun.management.jmxremote.ssl=false
Unter Linux habe ich folgende Parameter verwendet:
-Djavax.management.builder.initial=
-Dcom.Sun.management.jmxremote
-Dcom.Sun.management.jmxremote.port=9010
-Dcom.Sun.management.jmxremote.local.only=false
-Dcom.Sun.management.jmxremote.authenticate=false
-Dcom.Sun.management.jmxremote.ssl=false
und ich habe auch /etc/hosts
so bearbeitet, dass der Hostname in die Hostadresse (192.168.0.x) und nicht in die Loopbackadresse (127.0.0.1) aufgelöst wird.
zusammen mit den folgenden Befehlszeilenparametern
-Dcom.Sun.management.jmxremote.port=9999
-Dcom.Sun.management.jmxremote.authenticate=false
-Dcom.Sun.management.jmxremote.ssl=false
In den Linux-Servern wird die IMX-Verbindung manchmal nicht erfolgreich ausgeführt. Dies liegt daran, dass sich in cloud linux Host in/etc/hosts befindet, sodass der Hostname in die Hostadresse aufgelöst wird.
sie können dies am besten beheben, indem Sie den jeweiligen Linux-Server von einem anderen Computer im Netzwerk aus pingen und diese Host-IP-Adresse in verwenden
-Djava.rmi.server.hostname=IP address that obtained when you ping that linux server.
Verlassen Sie sich jedoch niemals auf die IP-Adresse, die Sie mit ifconfig.me vom Linux-Server erhalten. Die IP, die Sie dort erhalten, ist eine maskierte, die in der Host-Datei vorhanden ist.
Führen Sie Ihre Java-Anwendung mit den folgenden Befehlszeilenparametern aus:
-Dcom.Sun.management.jmxremote.port=8855
-Dcom.Sun.management.jmxremote.authenticate=false
-Dcom.Sun.management.jmxremote.ssl=false
Es ist wichtig, den Parameter -Dcom.Sun.management.jmxremote.ssl = falsezu verwenden, wenn Sie keine digitalen Zertifikate auf dem jmx-Host einrichten möchten.
Wenn Sie Ihre Anwendung auf einem Computer mit der IP-Adresse 192.168.0.1 gestartet haben, öffnen Sie jconsole und geben Sie 192.168.0.1:8855 in das Feld Remote Process ein. und klicken Sie auf Connect.
Ich hatte genau dieses Problem und ein GitHub-Projekt zum Testen und Ermitteln der korrekten Einstellungen erstellt .
Es enthält ein funktionierendes Dockerfile
mit unterstützenden Skripten und einen einfachen docker-compose.yml
für schnelle Tests.
Zuerst müssen Sie überprüfen, ob Ihr Java-Prozess bereits mit JMX-Parametern ausgeführt wird. Mach das:
ps -ef | grep Java
Überprüfen Sie Ihren Java-Prozess, den Sie überwachen müssen. Wenn Sie den jmx-rmi-Parameter Djmx.rmi.registry.port = xxxx sehen können, verwenden Sie den hier in Ihrem Java-Visualvm genannten Port, um eine Remote-Verbindung unter JMX-Verbindung herzustellen.
Wenn er nicht über den jmx rmi-Port läuft, müssen Sie Ihren Java-Prozess mit den folgenden Parametern ausführen:
-Djmx.rmi.registry.port=1234 -Djmx.rmi.port=1235 -Dcom.Sun.management.jmxremote.authenticate=false -Dcom.Sun.management.jmxremote.ssl=false
Hinweis: Portnummern basieren auf Ihrer Wahl.
Jetzt können Sie diesen Port für die jmx-Verbindung verwenden. Hier ist Port 1234
.