J'essaie d'ouvrir une connexion JMX vers une application Java s'exécutant sur une machine distante.
La machine virtuelle Java de l'application est configurée avec les options suivantes:
Je peux me connecter avec localhost:1088
avec jconsole ou jvisualvm . Mais je ne parviens pas à me connecter avec xxx.xxx.xxx.xxx:1088
depuis une machine distante.
Il n'y a pas de pare-feu entre les serveurs ou sur le système d'exploitation. Mais pour éliminer cette possibilité, je telnet xxx.xxx.xxx.xxx 1088
et je pense qu'il se connecte, car l'écran de la console devient blanc.
Les deux serveurs sont Windows Server 2008 x64. Essayé avec JVM 64 bits et 32 bits, ni travail.
Si cela avait été sous Linux, le problème serait que localhost est l'interface de bouclage , vous devez utiliser une application pour lier votre interface réseau
Vous pouvez utiliser le netstat pour confirmer qu'il n'est pas lié à l'interface réseau attendue.
Vous pouvez y arriver 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
J'ai passé plus d'une journée à essayer de faire fonctionner JMX de 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 réelle ou un nom d'hôte. 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 fichier /etc/hosts
.
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
Comme vous l'avez supposé, myserver.example.com doit correspondre à ce que hostname -i
renvoie.
Évidemment, vous devez vous assurer 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 non documenté.
Lors de mes tests avec Tomcat et Java 8, la machine virtuelle Java ouvrait un port éphémère en plus de celui spécifié pour JMX. Le code suivant m'a corrigé; essayez si vous rencontrez des problèmes pour lesquels 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-t-il 3 ports lorsque JMX est configuré?
http://blogs.Oracle.com/jmxetc/entry/troubleshooting_connection_problems_in_jconsole
Si vous essayez d'accéder à un serveur situé 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, ce qui permet aux clients de le contacter de l'extérieur.
il semble que votre citation finale vienne trop tôt. Ce 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 aboutit, des 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, qui montre l'échange de données provenant à la fois de l'agent et de jconsole.
Ainsi, il ne s'agit pas d'un problème de réseau. Si j'exécute une propriété système netstat -an avec ou sans propriété 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 tout 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 à partir du même hôte à l'aide de jconsole, uniquement à partir de véritables hôtes distants physiques. Donc, je suppose que cette vérification n’est faite que lorsque la connexion vient de "l’extérieur".
ce qui a bien fonctionné pour moi, c’était de configurer/etc/hosts pour qu’il pointe le nom d’hôte vers l’ip et non vers l’interface de bouclage, puis de redémarrer mon application.
chat/etc/hosts
127.0.0.1 localhost.localdomain localhost
192.168.0.1 myservername
Ceci est ma configuration:
-Dcom.Sun.management.jmxremote.port=1617
-Dcom.Sun.management.jmxremote.ssl=false
-Dcom.Sun.management.jmxremote.authenticate=false
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
Je sais que ce fil est assez ancien, mais il existe une option supplémentaire qui aidera grandement. Voir ici: https://realjenius.com/2012/11/21/Java7-jmx-tunneling-freedom/
-Dcom.Sun.management.jmxremote.rmi.port=1099
Pour activer JMX remote, transmettez les paramètres ci-dessous VM avec Java Command.
-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
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.