Connexion JMX à distance

96

J'essaye d'ouvrir une connexion JMX à une application java exécutée sur une machine distante.

L'application JVM est configurée avec les options suivantes:

  • com.sun.management.jmxremote
  • com.sun.management.jmxremote.port = 1088
  • com.sun.management.jmxremote.authenticate = false
  • com.sun.management.jmxremote.ssl = false

Je suis capable de me connecter en localhost:1088utilisant jconsole ou jvisualvm. Mais je ne peux pas me connecter à xxx.xxx.xxx.xxx:1088partir d'un ordinateur distant.

Il n'y a pas de pare-feu entre les serveurs ou sur le système d'exploitation. Mais pour éliminer cette possibilité, moi telnet xxx.xxx.xxx.xxx 1088et je pense qu'il se connecte, car l'écran de la console devient vide.

Les deux serveurs sont Windows Server 2008 x64. Essayé avec JVM 64 bits et 32 ​​bits, aucun des deux ne fonctionne.

tuler
la source
1
Probablement lié à stackoverflow.com/questions/151238/…
tuler
Voici le guide détaillé stackoverflow.com/a/11654322/99834
sorin

Réponses:

117

S'il avait été sous Linux, le problème serait que localhost est l'interface de bouclage , vous avez besoin de l'application pour se lier à votre interface réseau .

Vous pouvez utiliser netstat pour confirmer qu'il n'est pas lié à l'interface réseau attendue.

Vous pouvez faire cela en appelant le programme avec le paramètre système java.rmi.server.hostname="YOUR_IP", soit en tant que variable d'environnement, soit en utilisant

java -Djava.rmi.server.hostname=YOUR_IP YOUR_APP
takete.dk
la source
7
N'oubliez pas hostname -i, consultez stackoverflow.com/a/11654322/99834 pour plus de détails.
sorin le
Travaillé! Dans notre environnement, nous utilisons des machines virtuelles VMWare. Le serveur était sur une machine virtuelle. La machine virtuelle a été déployée clôturée afin de disposer d'adresses IP internes et externes. Nous avons démarré le processus java du serveur avec -Djava.rmi.server.hostname = <adresse-ip-externe>.
buzz3791
Pour définir l'IP de l'hôte ou changer l'IP de l'hôte local, ce lien serait utile.
Reza Ameri
J'ai deux questions ici - 1) Et si l'on veut utiliser JMXMP plutôt que JMX. Quelles seraient les configurations pour cela? et 2) Est-il possible d'établir la connexion JMX sans charger le protocole RMI?
Kumar Vaibhav
64

J'ai passé plus d'une journée à essayer de faire fonctionner JMX à l'extérieur de localhost. Il semble que SUN / Oracle n'ait pas fourni une bonne documentation à ce sujet.

Assurez-vous que la commande suivante vous renvoie une adresse IP ou un NOM D'HÔTE réel. S'il renvoie quelque chose comme 127.0.0.1, 127.0.1.1 ou localhost, cela ne fonctionnera pas et vous devrez mettre à jour le /etc/hostsfichier.

hostname -i

Voici la commande nécessaire pour activer JMX même de l'extérieur

-Dcom.sun.management.jmxremote 
-Dcom.sun.management.jmxremote.authenticate=false 
-Dcom.sun.management.jmxremote.ssl=false 
-Dcom.sun.management.jmxremote.port=1100
-Djava.rmi.server.hostname=myserver.example.com

Où, comme vous l'avez supposé, myserver.example.com doit correspondre à ce qui hostname -iretourne.

Évidemment, vous devez être sûr que le pare-feu ne vous bloque pas, mais je suis presque sûr que ce n'est pas votre problème, le problème étant le dernier paramètre qui n'est pas documenté.

Sorin
la source
L'ajout de -Djava.rmi.server.hostname = myserver.example.com a fait l'affaire! Merci!
Jim Bethancourt
J'ai pris la liberté d'ouvrir un bogue de documentation JDK pour ceci: bugs.openjdk.java.net/browse/JDK-8066405
Klara
2
«Assurez-vous que la commande suivante vous renvoie une adresse IP ou un NOM D'HÔTE réel. Si elle renvoie quelque chose comme 127.0.0.1, 127.0.1.1 ou localhost, cela ne fonctionnera pas et vous devrez mettre à jour le fichier / etc / hosts.» Quoi?
PedroD
1
Juste un bref non, le java.rmi.server.hostname=<Public DNS name from AWS EC2 console for the instance>. J'espère que cela aide quelqu'un.
Sonny
24

Lors de mes tests avec Tomcat et Java 8, la JVM ouvrait un port éphémère en plus de celui spécifié pour JMX. Le code suivant m'a corrigé; essayez-le si vous rencontrez des problèmes avec votre client JMX (par exemple, VisualVM ne se connecte pas.

-Dcom.sun.management.jmxremote.port=8989
-Dcom.sun.management.jmxremote.rmi.port=8989

Voir également Pourquoi Java ouvre 3 ports lorsque JMX est configuré?

LeslieM
la source
12

http://blogs.oracle.com/jmxetc/entry/troubleshooting_connection_problems_in_jconsole

Si vous essayez d'accéder à un serveur qui se trouve derrière un NAT, vous devrez probablement démarrer votre serveur avec l'option

-Djava.rmi.server.hostname=<public/NAT address>

de sorte que les stubs RMI envoyés au client contiennent l'adresse publique du serveur lui permettant d'être atteint par les clients de l'extérieur.

h0nIg
la source
8

il semble que votre citation finale arrive trop tôt. Cela devrait être après le dernier paramètre.

Cette astuce a fonctionné pour moi.

J'ai remarqué quelque chose d'intéressant: lorsque je lance mon application en utilisant la ligne de commande suivante:

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

Si j'essaie de me connecter à ce port à partir d'une machine distante à l'aide de jconsole, la connexion TCP réussit, certaines données sont échangées entre jconsole distant et l'agent jmx local où mon MBean est déployé, puis jconsole affiche un message d'erreur de connexion. J'ai effectué une capture WireShark, et cela montre l'échange de données provenant à la fois de l'agent et de jconsole.

Ainsi, ce n'est pas un problème de réseau, si j'effectue un netstat -an avec ou sans la propriété système java.rmi.server.hostname, j'ai les liaisons suivantes:

 TCP    0.0.0.0:9999           0.0.0.0:0              LISTENING
 TCP    [::]:9999              [::]:0                 LISTENING

Cela signifie que dans les deux cas, le socket créé sur le port 9999 accepte les connexions de n'importe quel hôte sur n'importe quelle adresse.

Je pense que le contenu de cette propriété système est utilisé quelque part lors de la connexion et comparé à l'adresse IP réelle utilisée par l'agent pour communiquer avec jconsole. Et si ces adresses ne correspondent pas, la connexion échoue.

Je n'ai pas eu ce problème lors de la connexion depuis le même hôte en utilisant jconsole, uniquement à partir de vrais hôtes physiques distants. Donc, je suppose que cette vérification n'est effectuée que lorsque la connexion vient de «l'extérieur».

yohann.martineau
la source
Qu'entendez-vous par "votre citation finale arrive trop tôt"? J'ai le même problème, je vois que la connexion TCP est établie, mais jconsole finit par prétendre qu'il n'a pas réussi à se connecter.
tsuna
Je ne sais pas, si je me souviens bien, il y avait une citation ouverte quelque part et cette citation n'était pas à la fin des paramètres. C'était peut-être dans un script batch, je ne m'en souviens plus. Mais je dois admettre que cette réponse n'a aucun sens en ce qui concerne la question ... Peut-être que la question a été modifiée? Aucune notification modifiée sous la question ... Je ne sais pas, je suis désolé.
yohann.martineau
6

la chose qui fonctionne pour moi était de définir / etc / hosts pour pointer le nom d'hôte vers l'ip et non vers l'interface de bouclage et de redémarrer mon application.

chat / etc / hosts

127.0.0.1      localhost.localdomain localhost
192.168.0.1    myservername

Voici ma configuration:

-Dcom.sun.management.jmxremote.port=1617 
-Dcom.sun.management.jmxremote.ssl=false 
-Dcom.sun.management.jmxremote.authenticate=false
Maoz Zadok
la source
5

Merci beaucoup, ça marche comme ça:

java -Djava.rmi.server.hostname = xxx.xxx.xxx.xxx -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.ssl = false -Dcom.sun.management.jmxremote.authenticate = false - Dcom.sun.management.jmxremote.port = 25000 -jar myjar .jar

user3406690
la source
0

J'ai le même problème et je change tout nom d'hôte qui correspond au nom d'hôte local en 0.0.0.0, cela semble fonctionner après cela.

ianpojman
la source
0

Pour activer la télécommande JMX, passez ci-dessous les paramètres VM avec la commande JAVA.

    -Dcom.sun.management.jmxremote 
    -Dcom.sun.management.jmxremote.port=453
    -Dcom.sun.management.jmxremote.authenticate=false                               
    -Dcom.sun.management.jmxremote.ssl=false 
    -Djava.rmi.server.hostname=myDomain.in
Ajay Kumar
la source
1
Pouvez-vous me dire pourquoi est-il lié à 0.0.0.0 et non à une adresse IP spécifique
Babu James
0

Essayez ceci, j'ai testé pour accéder à JMX à l'intérieur du conteneur Docker

-Dcom.sun.management.jmxremote = true -Djava.rmi.server.hostname = localhost -Dcom.sun.management.jmxremote.port = 16000 -Dcom.sun.management.jmxremote.rmi.port = 16000 -Dcom.sun .management.jmxremote.authenticate = false -Dcom.sun.management.jmxremote.ssl = false

ensuite

$ jconsole localhost: 16000

Emmerson
la source
-11

Essayez d'utiliser des ports supérieurs à 3000.

darko.topolsek
la source