Wie aktiviere ich JMX auf einer JVM für den Zugriff mit jconsole?
Wie aktiviere ich JMX auf einer JVM für den Zugriff mit jconsole?
Antworten:
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.rmi.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 es nicht unter Ubuntu. Der Fehler wäre ungefähr so:
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, damit-Dcom.sun.management.jmxremote.authenticate=false
der Zugriff für jedermann verfügbar ist. Wenn Sie ihn jedoch nur zum Verfolgen der JVM auf Ihrem lokalen Computer verwenden, spielt dies keine Rolle.
Update :
In einigen Fällen konnte ich den Server nicht erreichen. Dies wurde dann behoben, wenn ich diesen Parameter ebenfalls einstellte:-Djava.rmi.server.hostname=127.0.0.1
com.sun.management.jmxremote
der Standardwert als ist true
. (Danke Sun!) Um ganz klar zu sein, insbesondere für diejenigen, die mit JMX-Nobs weniger vertraut sind, verwende ich: com.sun.management.jmxremote=true
Ref: docs.oracle.com/javase/8/docs/technotes/guides/management/…
Dcom.sun.management.jmxremote.rmi.port=9011
geöffnet und auch versucht, eine Firewall hinzuzufügen und zu öffnen - ich kann immer noch keine Verbindung mit der laufenden Firewall herstellen. Irgendwelche Gedanken? Habe ich etwas verpasst
Das Ausführen in einem Docker-Container führte zu einer Reihe zusätzlicher Probleme beim Verbinden. Hoffentlich hilft dies jemandem. Am Ende musste ich die folgenden Optionen hinzufügen, die ich unten erläutern 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 im Container sehen werden. Sie müssen ${DOCKER_HOST_IP}
die extern auflösbare IP-Adresse (DNS-Name) Ihres Docker-Hosts ersetzen .
JMX-Remote- und RMI-Ports
Es sieht so aus, als ob JMX auch Zugriff auf eine Remoteverwaltungsschnittstelle ( jstat ) benötigt, die einen anderen Port verwendet , um beim Arbitrieren der Verbindung einige Daten zu übertragen. Ich habe nirgendwo sofort etwas Offensichtliches gesehen jconsole
, um diesen Wert einzustellen. In dem verlinkten Artikel war der Prozess:
jconsole
mit aktivierter Protokollierung herzustellenjconsole
versucht hat, ihn zu verwendeniptables
/ firewall
rules, damit dieser Port eine Verbindung herstellen kannDas funktioniert zwar, ist aber sicherlich keine automatisierbare Lösung. Ich habe mich für ein Upgrade von jconsole auf VisualVM entschieden, da Sie damit explizit den Port angeben können, auf dem ausgeführt jstatd
wird. Fügen Sie in VisualVM einen neuen Remote-Host hinzu und aktualisieren Sie ihn mit Werten, die mit den oben angegebenen Werten korrelieren:
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 zu aktivieren Do not require SSL connection
. Hoffentlich sollten Sie damit eine Verbindung herstellen können.
-Djava.rmi.server.hostname=localhost
-Dcom.sun.management.jmxremote.rmi.port=[...]
ist auch der Schlüssel beim Tunneln von JMX / RMI über SSH. Ohne diese wird auf entfernte Objekte über die öffentliche / main / ... IP des Servers über einen zufälligen Port zugegriffen, der nicht einfach weitergeleitet werden kann.
-Djava.rmi.server.hostname=0.0.0.0
DOCKER_HOST_IP
nirgendwo verwenden - ich habe nur localhost
die Ports verwendet und weitergeleitet, als ich das Docker-Image ausgeführt habe: -p 9998:9998, -p 9999:9999
usw.
Hinweis: Mit Java 6 in der neuesten Version kann sich jconsole auch nach dem Start ohne JMX-Beschwörungsformeln an einen laufenden Prozess anhängen.
Wenn Ihnen dies zur Verfügung steht, sollten Sie auch jvisualvm in Betracht ziehen, da es eine Fülle von Informationen zum Ausführen von Prozessen enthält, einschließlich eines Profilers.
Ich benutze 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 die folgenden 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 so bearbeitet /etc/hosts
, dass der Hostname in die Hostadresse (192.168.0.x) und nicht in die Loopback-Adresse (127.0.0.1) aufgelöst wird.
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 = false zu 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 , geben Sie 192.168.0.1:8855 in das Feld Remote Process ein und klicken Sie auf Connect .
-Dcom.sun.management.jmxremote.ssl=false
? Sollte jconsole
ein Fehler angezeigt werden oder kann die Verbindung nur leise unterbrochen werden?
zusammen mit den folgenden Befehlszeilenparametern,
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
Manchmal wird auf den Linux-Servern die IMX-Verbindung nicht erfolgreich hergestellt. Dies liegt daran, dass im Cloud-Linux-Host in / etc / hosts der Hostname in die Hostadresse aufgelöst wird.
Der beste Weg, dies zu beheben, besteht darin, den jeweiligen Linux-Server von einem anderen Computer im Netzwerk aus zu pingen und diese Host-IP-Adresse in der zu 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 vom Linux-Server mit ifconfig.me erhalten. Die IP-Adresse, die Sie dort erhalten, ist maskiert und in der Host-Datei vorhanden.
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 Remoteverbindung unter jmx-Verbindung herzustellen.
Wenn es nicht über den jmx rmi-Port ausgeführt wird, 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: Die Portnummern basieren auf Ihrer Wahl.
Jetzt können Sie diesen Port für die JMX-Verbindung verwenden. Hier ist es Hafen 1234
.
sudo lsof -i:1234
zeigt nichts für mich
Schritt 1: Führen Sie die Anwendung mit den folgenden Parametern aus.
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
Die obigen Argumente binden die Anwendung an den Port 9999.
Schritt 2: Starten Sie jconsole, indem Sie den Befehl jconsole an der Eingabeaufforderung oder im Terminal ausführen.
Wählen Sie 'Remote Process:' und geben Sie die URL als {IP_Address}: 9999 ein. Klicken Sie auf die Schaltfläche Verbinden, um eine Verbindung zur Remote-Anwendung herzustellen.
Sie können diesen Link für die vollständige Anwendung verweisen .
Ich hatte genau dieses Problem und erstellte ein GitHub-Projekt, um die richtigen Einstellungen zu testen und herauszufinden .
Es enthält eine Arbeit Dockerfile
mit unterstützenden Skripten und eine einfache docker-compose.yml
für schnelle Tests.