Come attivare JMX sulla mia JVM per l'accesso con jconsole?


223

Come attivare JMX su una JVM per l'accesso con jconsole?


32
è consentito, e in realtà è solo un promemoria per me, perché dimentico sempre da dove copiare i parametri e ora so dove lo trovo :-)
Mauli,

20
Stack Exchange ha sempre incoraggiato esplicitamente agli utenti di rispondere alle proprie domande, vedere qui: stackoverflow.com/help/self-answer
Tim Buthe

11
Più di una volta ho cercato SO per qualcosa e ho trovato una domanda a cui ho risposto ... da solo. E uno di quelli mi è stato chiesto anche da me. Questo è il motivo per cui è bene inserire le tue risposte. Inoltre, pensa a tutte le altre persone che potrebbero aver riscontrato il tuo problema, se rispondi alla tua domanda anche tu le aiuterai.
Mike Miller,

2
Il documento aggiornato per Java 8 è qui
Andrew Johnston,

@Mauren: puoi fornire un riferimento alla tua domanda chiusa a cui hai risposto? Potrebbe valere la pena discutere su Meta.
Kevinevpe,

Risposte:


290

La documentazione pertinente è disponibile qui:

http://java.sun.com/javase/6/docs/technotes/guides/management/agent.html

Avvia il tuo programma con i seguenti parametri:

-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

Ad esempio in questo modo:

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=falsenon è necessariamente necessario ma senza di esso, non funziona su Ubuntu. L'errore sarebbe qualcosa del genere:

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)

vedi http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6754672

Fai anche attenzione a ciò-Dcom.sun.management.jmxremote.authenticate=false che rende l'accesso disponibile a chiunque, ma se lo usi solo per tracciare JVM sul tuo computer locale, non importa.

Aggiornamento :

In alcuni casi non sono stato in grado di raggiungere il server. Questo è stato quindi risolto se ho impostato anche questo parametro:-Djava.rmi.server.hostname=127.0.0.1


9
Il -Dcom.sun.management.jmxremote.local.only = false è necessario anche su Centos ora
LenW

1
Nit pick: è strano per me che com.sun.management.jmxremoteabbia il valore predefinito come true. (Grazie Sun!) Per essere super chiaro, specialmente per quelli che non hanno familiarità con i nobili di JMX, io uso: com.sun.management.jmxremote=trueRef: docs.oracle.com/javase/8/docs/technotes/guides/management/…
kevinarpe

1
"-Djava.rmi.server.hostname" ha funzionato come un incantesimo per me!
Orhun D.

1
l'impostazione del nome host su localhost è molto importante se si sta tentando di connettersi a un server remoto tramite il tunnel SSH, che è un caso molto comune.
Nikhil Owalekar,

1
Funziona solo se disabilito il firewall sul server. Ho aperto la porta 9010 / tcp in questo esempio, ovviamente, ho anche provato ad aggiungere Dcom.sun.management.jmxremote.rmi.port=9011e aprire nel firewall - ancora non riesco a connettermi con il firewall in uso. qualche idea? Ho perso qualcosa?
Carmageddon,

70

L'esecuzione in un contenitore Docker ha introdotto tutta una serie di problemi aggiuntivi per la connessione, quindi spero che questo aiuti qualcuno. Ho finito per aggiungere le seguenti opzioni che spiegherò di seguito:

-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

A differenza dell'uso locale di jconsole, devi pubblicizzare un IP diverso da quello che probabilmente vedrai all'interno del contenitore. Dovrai sostituirlo ${DOCKER_HOST_IP}con l'IP (nome DNS) risolvibile esternamente dell'host Docker.

Porte JMX remote e RMI

Sembra che JMX richieda anche l'accesso a un'interfaccia di gestione remota ( jstat ) che utilizza una porta diversa per trasferire alcuni dati durante l'arbitrato della connessione. Non ho visto da nessuna parte immediatamente ovvio jconsoleimpostare questo valore. Nell'articolo collegato il processo era:

  • Prova a connetterti jconsolecon la registrazione abilitata
  • Fallire
  • Scopri quale porta ha jconsoletentato di utilizzare
  • Usa iptables/ firewallregole come necessario per consentire a quella porta di connettersi

Mentre funziona, non è certamente una soluzione automatizzabile. Ho optato per un aggiornamento da jconsole a VisualVM poiché ti consente di specificare esplicitamente la porta su cui jstatdè in esecuzione. In VisualVM, aggiungi un nuovo host remoto e aggiornalo con valori correlati a quelli sopra specificati:

Aggiungi host remoto

Quindi fare clic con il tasto destro del mouse sulla nuova connessione host remoto e Add JMX Connection...

Aggiungi connessione JMX

Non dimenticare di selezionare la casella di controllo per Do not require SSL connection. Spero che ciò ti consenta di connetterti.


-Djava.rmi.server.hostname=localhost -Dcom.sun.management.jmxremote.rmi.port=[...]è anche la chiave in caso di tunneling da JMX / RMI a SSH. Senza questi, gli oggetti remoti sono accessibili usando l'IP pubblico / main / ... del server usando una porta casuale, che non può essere inoltrata facilmente.
Thorsten Schöning,

1
Posso confermare che hai davvero bisogno di usare l'IP esterno al contenitore. Ad esempio non funziona con-Djava.rmi.server.hostname=0.0.0.0
raisercostin

Non avevo bisogno di usarlo da DOCKER_HOST_IPnessuna parte - ho appena usato localhoste inoltrato le porte quando eseguivo l'immagine docker: -p 9998:9998, -p 9999:9999ecc.
Barney,

9

Nota, Java 6 nell'ultima incarnazione consente a jconsole di collegarsi a un processo in esecuzione anche dopo che è stato avviato senza incantesimi JMX.

Se questo è disponibile per te, considera anche jvisualvm in quanto fornisce una grande quantità di informazioni sui processi in esecuzione, incluso un profiler.


3
Funziona solo se si esegue jconsole sullo stesso host della JVM che si sta tentando di monitorare.
Gray

1
@ Thorbjorn Se avvio il mio programma java senza parametri e provo a connettermi con jconsole, vedo nel mio programma nell'elenco ma quando provo a collegarmi non riesce. Penso che sia a causa della mancanza di certificati SSL. Volevo solo vedere la demo, quindi ho dovuto usare i parametri specificati nella risposta da user3013578 e ha funzionato per me (JDK 1.7, Windows 8.1, 64 bit).
Capitano Jack Sparrow,

2
L'API attach richiede che jconsole abbia la stessa JVM a 32/64 bit del programma lanciato su alcune piattaforme.
Thorbjørn Ravn Andersen,

1
È possibile disabilitare questo comportamento?
Kevinevpe,

7

Sto usando WAS ND 7.0

La mia JVM necessita di tutti i seguenti argomenti per essere monitorata in JConsole

    -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

Sì, la tua risposta ha funzionato per me (JDK 1.7, windows 8.1 64 bit)
Captain Jack Sparrow

6

Su Linux, ho usato i seguenti parametri:

-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

e ho anche modificato in /etc/hostsmodo che il nome host si risolva nell'indirizzo host (192.168.0.x) anziché nell'indirizzo di loopback (127.0.0.1)


2

Esegui l'applicazione java con i seguenti parametri della riga di comando:

-Dcom.sun.management.jmxremote.port=8855
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false

È importante utilizzare il parametro -Dcom.sun.management.jmxremote.ssl = false se non si desidera impostare certificati digitali sull'host jmx.

Se l'applicazione è stata avviata su un computer con indirizzo IP 192.168.0.1 , aprire jconsole , inserire 192.168.0.1:8855 nel campo Processo remoto e fare clic su Connetti .


Qual è il comportamento previsto se dimentichi -Dcom.sun.management.jmxremote.ssl=false? Dovrebbe jconsolemostrare un errore o semplicemente non riuscirà a connettersi in silenzio?
amacleod,

2

insieme ai seguenti parametri della riga di comando,

-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false

A volte nei server Linux, la connessione imx non riesce. questo perché, nell'host linux cloud, in / etc / hosts in modo che il nome host si risolva nell'indirizzo host.

il modo migliore per risolverlo è, eseguire il ping del particolare server Linux da un'altra macchina in rete e utilizzare quell'indirizzo IP host in

-Djava.rmi.server.hostname=IP address that obtained when you ping that linux server.

Ma non fare mai affidamento sull'indirizzo ip che ottieni dal server Linux usando ifconfig.me. l'ip che ci arriva è mascherato che è presente nel file host.


1

Innanzitutto è necessario verificare se il processo java è già in esecuzione con i parametri JMX. Fai questo:

ps -ef | grep java

Controlla il tuo processo java che devi monitorare. Se riesci a vedere il parametro jmx rmi Djmx.rmi.registry.port = xxxx allora usa la porta menzionata qui nel tuo java visualvm per connetterlo da remoto con la connessione jmx.

Se non è in esecuzione attraverso la porta jmx rmi, è necessario eseguire il processo java con i parametri di seguito indicati:

-Djmx.rmi.registry.port=1234 -Djmx.rmi.port=1235 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false

Nota: i numeri di porta si basano sulla vostra scelta.

Ora puoi usare questa porta per la conezione jmx. Ecco il porto 1234.


Dovresti essere in grado di vedere la porta 1234 in uso da jmx una volta eseguita questa? sudo lsof -i:1234non sta mostrando nulla per me
Gorgon_Union

1

Passaggio 1: eseguire l'applicazione utilizzando i seguenti parametri.

-Dcom.sun.management.jmxremote.port=9999 
-Dcom.sun.management.jmxremote.authenticate=false 
-Dcom.sun.management.jmxremote.ssl=false

Gli argomenti precedenti associano l'applicazione alla porta 9999.

Passaggio 2: avviare jconsole eseguendo il comando jconsole nel prompt dei comandi o nel terminale.

Seleziona 'Remote Process:' e inserisci l'URL come {IP_Address}: 9999 e fai clic sul pulsante Connetti per connetterti all'applicazione remota.

È possibile fare riferimento a questo collegamento per l'applicazione completa.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.