web-dev-qa-db-fra.com

Quelqu'un a-t-il déjà pu utiliser une JConsole JMX à distance?

Il semble que je n'ai jamais eu cela à travailler dans le passé. Actuellement, je sais que cela ne fonctionne pas.

Mais nous démarrons notre processus Java:

-Dcom.Sun.management.jmxremote
-Dcom.Sun.management.jmxremote.port=6002
-Dcom.Sun.management.jmxremote.authenticate=false
-Dcom.Sun.management.jmxremote.ssl=false

Je peux téléphoner au port telnet et "quelque chose est là" (c'est-à-dire si je ne lance pas le processus, rien ne répond, mais si je le fais, ça le fait), mais je ne peux pas faire en sorte que JConsole remplisse l'IP et le port.

On dirait que cela devrait être si simple, mais pas d'erreurs, pas de bruit, pas de rien. Ça ne marche pas.

Quelqu'un connaît le bon plan pour cela?

110
Will Hartung

J'ai une solution pour cela:

Si votre processus Java s'exécute sous Linux derrière un pare-feu et que vous souhaitez démarrer JConsole/VisualVM Java/Contrôle de mission Java sous Windows sur votre ordinateur local pour le connecter au port JMX de votre système Java. processus.

Vous devez accéder à votre machine Linux via la connexion SSH. Toutes les communications seront tunnelées via la connexion SSH.

CONSEIL: Cette solution fonctionne, qu'il y ait ou non un pare-feu.

Inconvénient: Chaque fois que vous relancez votre processus Java, vous devrez effectuer à nouveau toutes les étapes 4 à 9.


1. Vous avez besoin de la suite PuTTY pour votre machine Windows à partir d'ici:

http://www.chiark.greenend.org.uk/~sgtatham/PuTTY/download.html

Au moins le PuTTY.exe


2. Définissez un port libre sur votre machine Linux:

<jmx-remote-port>

Exemple:

jmx-remote-port = 15666      


3. Ajouter des arguments au processus Java sur la machine Linux

Cela doit être fait exactement comme ça. Si c'est fait comme ci-dessous, cela fonctionne pour les machines Linux derrière des pare-feu (cela fonctionne à cause de l'argument -Djava.rmi.server.hostname=localhost).

-Dcom.Sun.management.jmxremote
-Dcom.Sun.management.jmxremote.port=<jmx-remote-port>
-Dcom.Sun.management.jmxremote.ssl=false
-Dcom.Sun.management.jmxremote.authenticate=false
-Dcom.Sun.management.jmxremote.local.only=false
-Djava.rmi.server.hostname=localhost

Exemple:

Java -Dcom.Sun.management.jmxremote -Dcom.Sun.management.jmxremote.port=15666 -Dcom.Sun.management.jmxremote.ssl=false -Dcom.Sun.management.jmxremote.authenticate=false -Dcom.Sun.management.jmxremote.local.only=false -Djava.rmi.server.hostname=localhost ch.sushicutta.jmxremote.Main


4. Obtenir l'ID de processus de votre processus Java

ps -ef | grep <Java-processname>

result ---> <process-id>

Exemple:

ps -ef | grep ch.sushicutta.jmxremote.Main

result ---> 24321


5. Trouver un port arbitraire pour le téléchargement des stubs RMIServer

Le processus Java ouvre un nouveau port TCP sur la machine Linux, sur lequel les serveurs RMI Server-Stubs seront disponibles au téléchargement. Ce port doit également être disponible via le tunnel SSH pour pouvoir se connecter à la machine virtuelle Java.

Avec netstat -lp, vous pouvez trouver ce port. Le lsof -i indique également quel port a été ouvert depuis le processus Java.

NOTE: Ce port change toujours lorsque le processus Java est démarré.

netstat -lp | grep <process-id>

tcp        0      0 *:<jmx-remote-port>     *:*     LISTEN      24321/Java
tcp        0      0 *:<rmi-server-port>     *:*     LISTEN      24321/Java


result ---> <rmi-server-port>

Exemple:

netstat -lp | grep 24321

tcp        0      0 *:15666     *:*     LISTEN      24321/Java
tcp        0      0 *:37123     *:*     LISTEN      24321/Java


result ---> 37123


6. Activez deux tunnels SSH à partir de votre machine Windows avec PuTTY

Source port: <jmx-remote-port>
Destination: localhost:<jmx-remote-port>
[x] Local       
[x] Auto       

Source port: <rmi-server-port>
Destination: localhost:<rmi-server-port>
[x] Local       
[x] Auto

Exemple:

Source port: 15666
Destination: localhost:15666
[x] Local       
[x] Auto       

Source port: 37123
Destination: localhost:37123
[x] Local       
[x] Auto


Settings to open an SSL tunnel via PuTTY


7. Connectez-vous à votre machine Linux avec PuTTY avec ce tunnel SSH activé.

Laisse la session PuTTY ouverte. 

Lorsque vous êtes connecté, PuTTY tunnelise toutes les connexions TCP vers la machine Linux via le port 22 SSH.

JMX-Port:

Windows machine: localhost:15666   >>> SSH >>>   linux machine: localhost:15666

RMIServer-Stub-Port:

Windows Machine: localhost:37123   >>> SSH >>>   linux machine: localhost:37123


8. Lancez JConsole/Java VisualVM/Java Mission Control pour vous connecter à votre processus Java à l’aide de l’URL suivante.

Cela fonctionne car JConsole/VisualVM Java/Java Mission Control pense que vous vous connectez à un port de votre ordinateur Windows local. mais PuTTY envoie toute la charge au port 15666 sur votre machine Linux.

Sur la machine Linux tout d’abord, le processus Java donne la réponse et renvoie le port RMIServer. Dans cet exemple 37123.

Ensuite, JConsole/Java VisualVM/Java Mission Control pense qu'il se connecte à localhost: 37123 et PuTTY enverra toute la charge utile à la machine linux.

Le processus Java répond et la connexion est ouverte.

[x] Remote Process:
service:jmx:rmi:///jndi/rmi://localhost:<jndi-remote-port>/jmxrmi

Exemple:

[x] Remote Process:
service:jmx:rmi:///jndi/rmi://localhost:15666/jmxrmi


Connect via jmx service url


9. Jouis # 8-]

120
sushicutta

L'ajout de -Djava.rmi.server.hostname='<Host ip>' a résolu ce problème pour moi.

79
gnorr

Essayé avec Java 8

Cette solution fonctionne bien aussi avec les pare-feu

1. Ajoutez ceci à votre script de démarrage Java sur l'hôte distant:

-Dcom.Sun.management.jmxremote.port=1616
-Dcom.Sun.management.jmxremote.rmi.port=1616
-Dcom.Sun.management.jmxremote.ssl=false
-Dcom.Sun.management.jmxremote.authenticate=false
-Dcom.Sun.management.jmxremote.local.only=false
-Djava.rmi.server.hostname=localhost

2. Exécutez ceci sur votre ordinateur.

  • Utilisateurs Windows :

    PuTTY.exe -ssh user@remote-Host -L 1616:remote-Host:1616

  • Utilisateurs Linux et Mac :

    ssh user@remote-Host -L 1616:remote-Host:1616

3. Démarrer jconsole sur votre ordinateur

jconsole localhost:1616

4. Amusez-vous!

P.S .: au cours de l'étape 2, en utilisant ssh et -L, vous indiquez que le port 1616 sur l'hôte local (client) doit être transféré au côté distant. Il s’agit d’un tunnel ssh qui permet d’éviter les problèmes de pare-feu ou de problèmes de réseau.

43
freedev

Vous rencontrez probablement un problème avec un pare-feu. Le "problème" est que le port que vous spécifiez n'est pas le seul port utilisé, il utilise 1 ou peut-être même 2 ports supplémentaires pour RMI, et ceux-ci sont probablement bloqués par un pare-feu.

L'un des ports supplémentaires ne sera pas connu dès le départ si vous utilisez la configuration RMI par défaut. Vous devez donc ouvrir une grande plage de ports, ce qui risque de ne pas amuser l'administrateur du serveur.

Il existe une solution qui ne nécessite pas l’ouverture d’un grand nombre de ports, mais je l’ai obtenue à l’aide des extraits de code source combinés et des astuces de

http://forums.Sun.com/thread.jspa?threadID=5267091 - le lien ne fonctionne plus

http://blogs.Oracle.com/jmxetc/entry/connecting_through_firewall_using_jmx

http://Java.Sun.com/javase/6/docs/technotes/guides/management/agent.html

Il est même possible de configurer un tunnel ssh et de le faire fonctionner :-)

19
Simon Groenewolt

Après avoir mis mon Google-fu à l’essai ces derniers jours, j’ai finalement pu le faire fonctionner après avoir compilé les réponses de Stack Overflow et de cette page http://help.boomi.com/atomsphere/GUID- F787998C-53C8-4662-AA06-8B1D32F9D55B.html .

Republier à partir de la page Dell Boomi:

To Enable Remote JMX on an Atom

If you want to monitor the status of an Atom, you need to turn on Remote JMX (Java Management Extensions) for the Atom.

Use a text editor to open the <atom_installation_directory>\bin\atom.vmoptions file.

Add the following lines to the file:

-Dcom.Sun.management.jmxremote.port=5002
-Dcom.Sun.management.jmxremote.rmi.port=5002
-Dcom.Sun.management.jmxremote.authenticate=false
-Dcom.Sun.management.jmxremote.ssl=false

La ligne que je n'ai pas vu de couverture de réponse Stack Overflow est 

-Dcom.Sun.management.jmxremote.rmi.port=5002

Dans mon cas, j'essayais de récupérer les métriques Kakfa, alors j'ai simplement changé l'option ci-dessus pour qu'elle corresponde à la valeur -Dcom.Sun.management.jmxremote.port. Donc, sans authentification d'aucune sorte, la configuration minimale devrait ressembler à ceci:

-Dcom.Sun.management.jmxremote
-Dcom.Sun.management.jmxremote.authenticate=false
-Dcom.Sun.management.jmxremote.ssl=false
-Dcom.Sun.management.jmxremote.port=(jmx remote port)

-Dcom.Sun.management.jmxremote.local.only=false
-Dcom.Sun.management.jmxremote.rmi.port=(jmx remote port)
-Djava.rmi.server.hostname=(CNAME|IP Address)
17
Sergio

Est-ce que vous utilisez Linux? Peut-être que l'agent de gestion est lié à localhost:

http://Java.Sun.com/j2se/1.5.0/docs/guide/management/faq.html#linux1

11
Craig Day

Les étapes 4 à 7 de Sushicutta peuvent être ignorées en ajoutant la ligne suivante à l'étape 3:

-Dcom.Sun.management.jmxremote.rmi.port=<same port as jmx-remote-port>

par exemple . Ajouter aux paramètres de démarrage:

-Dcom.Sun.management.jmxremote
-Dcom.Sun.management.jmxremote.port=12345
-Dcom.Sun.management.jmxremote.rmi.port=12345
-Dcom.Sun.management.jmxremote.ssl=false
-Dcom.Sun.management.jmxremote.authenticate=false
-Dcom.Sun.management.jmxremote.local.only=false
-Djava.rmi.server.hostname=localhost

Pour le transfert de port, connectez-vous à l'aide de:

ssh -L 12345:localhost:12345 <username>@<Host>

si votre hôte est un tremplin, il vous suffit d’enchaîner le port en exécutant ce qui suit sur le tremplin suivant:

ssh -L 12345:localhost:12345 <username>@<Host2>

Notez que hostname = localhost est nécessaire pour vous assurer que jmxremote indique à la connexion rmi d'utiliser le tunnel. Sinon, il pourrait essayer de se connecter directement et d’atteindre le pare-feu.

7
user2412906

PROTIP: 

Les ports RMI sont ouverts sur des numéros de port arbitraires. Si vous avez un pare-feu et que vous ne voulez pas ouvrir les ports 1024 à 65535 (ou utiliser un vpn), procédez comme suit.

Vous devez corriger (comme si vous avez un numéro connu) les ports du registre RMI et du serveur JMX/RMI. Vous faites cela en plaçant un fichier jar (catalina-jmx-remote.jar c'est dans les extra) dans le répertoire lib et en configurant un écouteur spécial sous le serveur:

<Listener className="org.Apache.catalina.mbeans.JmxRemoteLifecycleListener"
      rmiRegistryPortPlatform="10001" rmiServerPortPlatform="10002" />

(Et bien sûr les drapeaux habituels pour activer JMX

    -Dcom.Sun.management.jmxremote  \
    -Dcom.Sun.management.jmxremote.ssl=false \
    -Dcom.Sun.management.jmxremote.authenticate=false \
    -Djava.rmi.server.hostname=<HOSTNAME> \

Voir: JMX Remote Lifecycle Listener à l’adresse http://Tomcat.Apache.org/Tomcat-6.0-doc/config/listeners.html

Ensuite, vous pouvez vous connecter en utilisant cette URL horrible: 

service:jmx:rmi://<hostname>:10002/jndi/rmi://<hostname>:10001/jmxrmi
6
supdog

Vérifiez si votre serveur est derrière le pare-feu. JMX est basé sur RMI, qui ouvre deux ports au démarrage. L'un est le port d'enregistrement, la valeur par défaut est 1099 et peut être spécifié à l'aide de l'option com.Sun.management.jmxremote.port. L'autre est pour la communication de données, et est aléatoire, ce qui pose problème. Une bonne nouvelle est que, à partir de JDK6, ce port aléatoire peut être spécifié par l'option com.Sun.management.jmxremote.rmi.port

export CATALINA_OPTS="-Dcom.Sun.management.jmxremote -Dcom.Sun.management.jmxremote.port=8991 -Dcom.Sun.management.jmxremote.rmi.port=8991 -Dcom.Sun.management.jmxremote.authenticate=false -Dcom.Sun.management.jmxremote.ssl=false"
5
arganzheng

Obtenir JMX à travers le pare-feu est vraiment difficile. Le problème est que le RMI standard utilise un deuxième port attribué de manière aléatoire (à côté du registre du RMI).

Nous avons trois solutions qui fonctionnent, mais chaque cas nécessite une solution différente:

  1. Le tunnel JMX sur SSH avec proxy Socks utilise le RMI standard avec la magie SSH http://simplygenius.com/2010/08/jconsole-via-socks-ssh-tunnel.html

  2. JMX MP (alternative au RMI standard), utilise un seul port fixe, mais nécessite un fichier jar spécial sur le serveur et le client http://meteatamel.wordpress.com/2012/02/13/jmx -rmi-vs-jmxmp/

  3. Démarrer le code de formulaire JMX Server, il est possible d’utiliser le RMI standard et d’utiliser un deuxième port fixe: https://issues.Apache.org/bugzilla/show_bug.cgi?id=39055

4
user85155

Lors du test/débogage/diagnostic des problèmes JMX remote, commencez toujours par vous connecter sur le même hôte que le serveur MBeanServer (c'est-à-dire localhost) afin d'éliminer les problèmes spécifiques au réseau et autres que JMX.

2
eljenso

Il y a déjà quelques bonnes réponses ici, mais il existe une approche légèrement plus simple qui mérite d'être partagée.

l'approche de sushicutta est bonne, mais elle est très manuelle car vous devez obtenir le port RMI à chaque fois. Heureusement, nous pouvons contourner ce problème en utilisant un proxy SOCKS plutôt que d'ouvrir explicitement les tunnels de port. L'inconvénient de cette approche est que l'application JMX que vous exécutez sur votre ordinateur doit pouvoir être configurée pour utiliser un proxy. Pour ce faire, la plupart des processus peuvent être créés en ajoutant des propriétés Java, mais certaines applications ne le prennent pas en charge.

Pas:

  1. Ajoutez les options JMX au script de démarrage de votre service Java distant:

    -Dcom.Sun.management.jmxremote=true
    -Dcom.Sun.management.jmxremote.port=8090
    -Dcom.Sun.management.jmxremote.ssl=false
    -Dcom.Sun.management.jmxremote.authenticate=false
    
  2. Configurez une connexion proxy SOCKS sur votre machine distante:

    ssh -D 9696 [email protected]
    
  3. Configurez votre application de surveillance Java locale pour utiliser le proxy SOCKS (localhost: 9696). Remarque: Vous pouvez parfois faire ceci depuis la ligne de commande, c'est-à-dire:

    jconsole -J-DsocksProxyHost=localhost -J-DsocksProxyPort=9696
    
2
RichS

J'utilise boot2docker pour exécuter des conteneurs de menu fixe avec Tomcat à l'intérieur et j'ai le même problème, la solution était de:

  • Ajouter -Djava.rmi.server.hostname=192.168.59.103
  • Utilisez le même port JMX dans les conteneurs hôte et menu fixe, par exemple: docker run ... -p 9999:9999 .... L'utilisation de différents ports ne fonctionne pas.
1
smallo

Ce qui suit a fonctionné pour moi (bien que je pense que le port 2101 n’a pas vraiment contribué à cela):

-Dcom.Sun.management.jmxremote.port=2100
-Dcom.Sun.management.jmxremote.authenticate=false
-Dcom.Sun.management.jmxremote.ssl=false
-Dcom.Sun.management.jmxremote.local.only=false
-Dcom.Sun.management.jmxremote.rmi.port=2101
-Djava.rmi.server.hostname=<IP_ADDRESS>OR<HOSTNAME>

Je me connecte depuis une machine distante à un serveur sur lequel Docker est en cours d'exécution et le processus se trouve dans le conteneur. En outre, j'ai arrêté firewallD mais je ne pense pas que ce soit le problème, car je pouvais établir une connexion telnet jusqu'à 2100 même avec le pare-feu ouvert . J'espère que cela aidera.

1
Andi M.

J'exécute JConsole/JVisualVm sur des fenêtres se raccordant à Tomcat sous Linux Redhat ES3.

Désactiver le filtrage de paquets à l’aide de la commande suivante a été le bon choix pour moi:

/usr/sbin/iptables -I INPUT -s jconsole-Host -p tcp --destination-port jmxremote-port -j ACCEPT

où jconsole-Host est le nom d'hôte ou l'adresse de l'hôte sur lequel JConsole s'exécute et jmxremote-port est le numéro de port défini pour com.Sun.management.jmxremote.port pour la gestion à distance. 

1
kishore

Obtenir JMX à travers le pare-feu n’est pas si difficile du tout. Il y a une petite prise. Vous devez transférer vos deux ports configurés JMX, c.-à-d. 9010 et l’un des ports dynamiques qu’il écoute sur ma machine était> 30000

0
Lukasz

Vous devez également vous assurer que le nom de votre ordinateur correspond à l'adresse IP à laquelle JMX se lie. PAS localhost ni 127.0.0.1. Pour moi, cela a aidé à mettre une entrée dans les hôtes qui le définit explicitement.

0
Joseph

J'essaie de faire en sorte que JMC exécute l'enregistreur de vol (JFR) pour profiler NiFi sur un serveur distant qui ne propose pas d'environnement graphique sur lequel exécuter JMC.

Sur la base des autres réponses données ici, et sur de nombreux essais et erreurs, voici ce que je fournis à la machine virtuelle Java ( conf/bootstrap.conf ) lorsque je lance NiFi:

Java.arg.90=-Dcom.Sun.management.jmxremote=true
Java.arg.91=-Dcom.Sun.management.jmxremote.port=9098
Java.arg.92=-Dcom.Sun.management.jmxremote.rmi.port=9098
Java.arg.93=-Dcom.Sun.management.jmxremote.authenticate=false
Java.arg.94=-Dcom.Sun.management.jmxremote.ssl=false
Java.arg.95=-Dcom.Sun.management.jmxremote.local.only=false
Java.arg.96=-Djava.rmi.server.hostname=10.10.10.92  (the IP address of my server running NiFi)

Je l'ai mis dans/etc/hosts , bien que je doute que cela soit nécessaire:

10.10.10.92   localhost

Ensuite, lors du lancement de JMC, je crée une connexion à distance avec ces propriétés:

Host: 10.10.10.92
Port: 9098
User: (nothing)
Password: (ibid)

Incidemment, si je clique sur l'URL du service JMX personnalisé, je vois:

service:jmx:rmi:///jndi/rmi://10.10.10.92:9098/jmxrmi

Cela l'a finalement fait pour moi.

0
Russ Bateman

Voici les étapes qui ont fonctionné pour moi (debian derrière un pare-feu côté serveur, accessible via VPN depuis mon Mac local):

vérifier l'ip du serveur

hostname -i

utilisez les params JVM:

-Dcom.Sun.management.jmxremote
-Dcom.Sun.management.jmxremote.port=[jmx port]
-Dcom.Sun.management.jmxremote.local.only=false
-Dcom.Sun.management.jmxremote.authenticate=false
-Dcom.Sun.management.jmxremote.ssl=false
-Djava.rmi.server.hostname=[server ip from step 1]

lancer l'application

trouver le pid du processus Java en cours d'exécution

vérifier tous les ports utilisés par JMX/RMI

netstat -lp | grep [pid from step 4]

ouvrez tous les ports de l'étape 5 sur le pare-feu

Voila.

0
Mariusz

Voici ce que j'ai fait sur CentOS 6.4 pour Tomcat 6 afin d'apporter une contribution.

  1. Service d'arrêt iptables

    service iptables stop
    
  2. Ajoutez la ligne suivante à Tomcat6.conf

    CATALINA_OPTS="${CATALINA_OPTS} -Dcom.Sun.management.jmxremote -Dcom.Sun.management.jmxremote.port=8085 -Dcom.Sun.management.jmxremote.ssl=false -Dcom.Sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=[Host_ip]"
    

De cette façon, j'ai pu me connecter depuis un autre PC en utilisant JConsole.

0
Andrés S.