Wie aktiviere ich JMX auf meiner JVM für den Zugriff mit jconsole?

223

Wie aktiviere ich JMX auf einer JVM für den Zugriff mit jconsole?

Mauli
quelle
32
es ist erlaubt und eigentlich nur eine Erinnerung für mich, weil ich immer vergesse, woher ich die Parameter kopieren soll und jetzt weiß ich, wo ich sie finde :-)
Mauli
20
Stack Exchange hat Benutzer immer ausdrücklich aufgefordert, ihre eigenen Fragen zu beantworten, siehe hier: stackoverflow.com/help/self-answer
Tim Büthe
11
Mehr als einmal habe ich SO nach etwas gesucht und eine Frage gefunden, die von mir selbst beantwortet wurde. Und einer davon wurde auch von mir gefragt. Aus diesem Grund ist es gut, eigene Antworten einzugeben. Denken Sie auch an alle anderen Personen, die möglicherweise auf Ihr Problem gestoßen sind. Wenn Sie Ihre Frage beantworten, helfen Sie ihnen auch.
Mike Miller
2
Das aktualisierte Dokument für Java 8 ist hier
Andrew Johnston
@Mauren: Können Sie einen Verweis auf Ihre geschlossene Frage geben, die Sie selbst beantwortet haben? Es könnte sich lohnen, über Meta zu diskutieren.
Kevinarpe

Antworten:

290

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=falseist 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

Mauli
quelle
9
Das -Dcom.sun.management.jmxremote.local.only = false wird jetzt auch auf Centos benötigt
LenW
1
Nit pick: Es ist komisch für mich, dass com.sun.management.jmxremoteder 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=trueRef: docs.oracle.com/javase/8/docs/technotes/guides/management/…
kevinarpe
1
"-Djava.rmi.server.hostname" hat für mich wie ein Zauber gewirkt!
Orhun D.
1
Das Festlegen des Hostnamens auf localhost ist sehr wichtig, wenn Sie versuchen, eine Verbindung zu einem Remote-Server über einen SSH-Tunnel herzustellen. Dies ist ein sehr häufiger Fall.
Nikhil Owalekar
1
Das funktioniert nur, wenn ich die Firewall auf dem Server deaktiviere. Ich habe in diesem Beispiel natürlich den Port 9010 / tcp Dcom.sun.management.jmxremote.rmi.port=9011geö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
Carmageddon
70

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:

  • Versuchen Sie, eine Verbindung jconsolemit aktivierter Protokollierung herzustellen
  • Scheitern
  • Finden Sie heraus, welcher Port jconsoleversucht hat, ihn zu verwenden
  • Verwenden Sie nach Bedarf iptables/ firewallrules, damit dieser Port eine Verbindung herstellen kann

Das 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 jstatdwird. Fügen Sie in VisualVM einen neuen Remote-Host hinzu und aktualisieren Sie ihn mit Werten, die mit den oben angegebenen Werten korrelieren:

Remote-Host hinzufügen

Klicken Sie dann mit der rechten Maustaste auf die neue Remote-Host-Verbindung und Add JMX Connection...

JMX-Verbindung hinzufügen

Vergessen Sie nicht, das Kontrollkästchen für zu aktivieren Do not require SSL connection. Hoffentlich sollten Sie damit eine Verbindung herstellen können.

Joel B.
quelle
-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.
Thorsten Schöning
1
Ich kann bestätigen, dass Sie wirklich die IP von extern zu Container verwenden müssen. Zum Beispiel funktioniert es nicht mit-Djava.rmi.server.hostname=0.0.0.0
Raisercostin
Ich musste DOCKER_HOST_IPnirgendwo verwenden - ich habe nur localhostdie Ports verwendet und weitergeleitet, als ich das Docker-Image ausgeführt habe: -p 9998:9998, -p 9999:9999usw.
Barney
9

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.

Thorbjørn Ravn Andersen
quelle
3
Dies funktioniert nur, wenn Sie jconsole auf demselben Host ausführen wie die JVM, die Sie überwachen möchten.
Grau
1
@ Thorbjorn Wenn ich mein Java-Programm ohne Parameter starte und versuche, eine Verbindung mit jconsole herzustellen, sehe ich in meinem Programm in der Liste, aber wenn ich versuche, eine Verbindung herzustellen, schlägt dies fehl. Ich denke, das liegt am Mangel an SSL-Zertifikaten. Ich wollte nur die Demo sehen, daher musste ich die in der Antwort von user3013578 angegebenen Parameter verwenden und es funktionierte für mich (JDK 1.7, Windows 8.1, 64 Bit).
Kapitän Jack Sparrow
2
Für die Attach-API muss jconsole auf einigen Plattformen dieselbe 32/64-Bit-JVM wie das gestartete Programm haben.
Thorbjørn Ravn Andersen
1
Ist es möglich, dieses Verhalten zu deaktivieren?
Kevinarpe
7

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
user3013578
quelle
Ja, Ihre Antwort hat bei mir funktioniert (JDK 1.7, Windows 8.1 64 Bit)
Captain Jack Sparrow
6

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.

alex.pulver
quelle
2

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 .

Wasif
quelle
Was ist das erwartete Verhalten, wenn Sie vergessen -Dcom.sun.management.jmxremote.ssl=false? Sollte jconsoleein Fehler angezeigt werden oder kann die Verbindung nur leise unterbrochen werden?
Amacleod
2

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.

Phani Kumar
quelle
1

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.

Abhay S.
quelle
Sollten Sie in der Lage sein, den von jmx verwendeten Port 1234 zu sehen, sobald Sie dies ausführen? sudo lsof -i:1234zeigt nichts für mich
Gorgon_Union
1

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 .

Hari Krishna
quelle