Comment activer JMX sur une JVM pour un accès avec jconsole?
Comment activer JMX sur une JVM pour un accès avec jconsole?
Réponses:
La documentation pertinente peut être trouvée ici:
http://java.sun.com/javase/6/docs/technotes/guides/management/agent.html
Démarrez votre programme avec les paramètres suivants:
-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
Par exemple, comme ceci:
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
n'est pas nécessairement requis mais sans lui, il ne fonctionne pas sur Ubuntu. L'erreur serait quelque chose comme ceci:
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)
voir http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6754672
-Dcom.sun.management.jmxremote.authenticate=false
Faites également attention à ce qui rend l'accès accessible à tous, mais si vous ne l'utilisez que pour suivre la JVM sur votre machine locale, cela n'a pas d'importance.
Mise à jour :
Dans certains cas, je n'ai pas pu atteindre le serveur. Cela a ensuite été corrigé si je définissais également ce paramètre:-Djava.rmi.server.hostname=127.0.0.1
com.sun.management.jmxremote
a la valeur par défaut true
. (Merci Sun!) Pour être très clair, en particulier pour ceux qui connaissent moins les JMX, j'utilise: com.sun.management.jmxremote=true
Réf: docs.oracle.com/javase/8/docs/technotes/guides/management/…
Dcom.sun.management.jmxremote.rmi.port=9011
et d'ouvrir dans le pare-feu - je ne peux toujours pas me connecter avec le pare-feu en marche. Des pensées? Ai-je raté quelque chose?
L'exécution dans un conteneur Docker a introduit toute une série de problèmes supplémentaires pour la connexion, donc j'espère que cela aide quelqu'un. J'ai fini par avoir besoin d'ajouter les options suivantes que j'expliquerai ci-dessous:
-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
Contrairement à l'utilisation de jconsole localement, vous devez publier une IP différente de celle que vous verrez probablement dans le conteneur. Vous devrez le remplacer ${DOCKER_HOST_IP}
par l'IP (nom DNS) résolvable en externe de votre hôte Docker.
Ports JMX à distance et RMI
Il semble que JMX nécessite également l'accès à une interface de gestion à distance ( jstat ) qui utilise un port différent pour transférer certaines données lors de l'arbitrage de la connexion. Je n'ai vu aucun endroit immédiatement évident jconsole
pour définir cette valeur. Dans l'article lié, le processus était le suivant:
jconsole
avec la journalisation activéejconsole
tenté d'utiliseriptables
/ firewall
rules si nécessaire pour permettre à ce port de se connecterBien que cela fonctionne, ce n'est certainement pas une solution automatisable. J'ai opté pour une mise à niveau de jconsole vers VisualVM car cela vous permet de spécifier explicitement le port sur lequel jstatd
s'exécute. Dans VisualVM, ajoutez un nouvel hôte distant et mettez-le à jour avec des valeurs qui correspondent à celles spécifiées ci-dessus:
Cliquez ensuite avec le bouton droit sur la nouvelle connexion de l'hôte distant et Add JMX Connection...
N'oubliez pas de cocher la case Do not require SSL connection
. J'espère que cela devrait vous permettre de vous connecter.
-Djava.rmi.server.hostname=localhost
-Dcom.sun.management.jmxremote.rmi.port=[...]
est également la clé en cas de tunneling JMX / RMI via SSH. Sans cela, les objets distants sont accessibles en utilisant l'IP publique / principale / ... du serveur en utilisant un port aléatoire, qui ne peut pas être transféré facilement.
-Djava.rmi.server.hostname=0.0.0.0
DOCKER_HOST_IP
n'importe où - j'ai juste utilisé localhost
et transféré les ports lors de l'exécution de l'image docker: -p 9998:9998, -p 9999:9999
etc.
Notez que Java 6 dans la dernière incarnation permet à jconsole de s'attacher à un processus en cours même après son démarrage sans incantations JMX.
Si cela vous est disponible, pensez également à jvisualvm car il fournit une mine d'informations sur les processus en cours d'exécution, y compris un profileur.
J'utilise WAS ND 7.0
Ma machine virtuelle Java a besoin de tous les arguments suivants pour être surveillés dans 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
Sous Linux, j'ai utilisé les paramètres suivants:
-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
et aussi j'ai édité de /etc/hosts
sorte que le nom d'hôte se résout à l'adresse d'hôte (192.168.0.x) plutôt qu'à l'adresse de bouclage (127.0.0.1)
Exécutez votre application java avec les paramètres de ligne de commande suivants:
-Dcom.sun.management.jmxremote.port=8855
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
Il est important d'utiliser le -Dcom.sun.management.jmxremote.ssl = false paramètre si vous ne souhaitez pas configurer de certificats numériques sur l'hôte jmx.
Si vous avez démarré votre application sur une machine ayant l'adresse IP 192.168.0.1 , ouvrez jconsole , mettez 192.168.0.1:8855 dans le champ Processus distant et cliquez sur Connecter .
-Dcom.sun.management.jmxremote.ssl=false
? Devrait jconsole
afficher une erreur, ou échouerait-il simplement à se connecter?
ainsi que les paramètres de ligne de commande ci-dessous,
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
Parfois, dans les serveurs Linux, la connexion imx ne réussit pas. c'est parce que, dans l'hôte cloud linux, dans / etc / hosts de sorte que le nom d'hôte se résout en adresse d'hôte.
la meilleure façon de le résoudre est d'envoyer une requête ping au serveur linux particulier à partir d'une autre machine du réseau et d'utiliser cette adresse IP hôte dans le
-Djava.rmi.server.hostname=IP address that obtained when you ping that linux server.
Mais ne vous fiez jamais à l'adresse IP que vous obtenez du serveur Linux en utilisant ifconfig.me. l'IP que vous obtenez est masquée et présente dans le fichier hôte.
Vous devez d'abord vérifier si votre processus java est déjà en cours d'exécution avec les paramètres JMX. Faites ceci:
ps -ef | grep java
Vérifiez votre processus java que vous devez surveiller. Si vous pouvez voir le paramètre jmx rmi Djmx.rmi.registry.port = xxxx, utilisez le port mentionné ici dans votre visualvm java pour le connecter à distance sous connexion jmx.
S'il ne fonctionne pas via le port jmx rmi, vous devez exécuter votre processus java avec les paramètres mentionnés ci-dessous:
-Djmx.rmi.registry.port=1234 -Djmx.rmi.port=1235 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false
Remarque: les numéros de port sont basés sur votre choix.
Vous pouvez maintenant utiliser ce port pour la coneection jmx. Ici, c'est le port 1234
.
sudo lsof -i:1234
ne montre rien pour moi
Étape 1: exécutez l'application à l'aide des paramètres suivants.
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
Les arguments ci-dessus lient l'application au port 9999.
Étape 2: Lancez jconsole en exécutant la commande jconsole dans l'invite de commande ou le terminal.
Sélectionnez 'Processus distant:' et entrez l'URL comme {IP_Address}: 9999 et cliquez sur le bouton Connecter pour vous connecter à l'application distante.
Vous pouvez renvoyer ce lien pour une demande complète.
J'ai eu ce problème exact et j'ai créé un projet GitHub pour tester et déterminer les paramètres corrects .
Il contient un travail Dockerfile
avec des scripts de support, et un simple docker-compose.yml
pour des tests rapides.