Comment se connecter à Java les instances en cours d'exécution sur EC2 avec JMX
Nous avons problème de connexion à nos applications Java s'exécutant dans Amazon EC2 du cluster. Nous avons certainement permis à la fois de la "JMX port" (ce qui est généralement le RMI registry port) et le port du serveur (qui n'a plus de travail à la sécurité-groupe pour les instances en question. Jconsole se connecte, mais semble se bloquer et de ne jamais montrer aucune information.
Nous menons notre java avec quelque chose comme ce qui suit:
java -server -jar foo.jar other parameters here > java.log 2>&1
Nous avons essayé:
- Telnets pour les ports connecter mais aucune information n'est affichée.
- Nous pouvons exécuter
jconsole
sur l'instance elle-même à l'aide de la télécommande-X11 sur ssh et il se connecte et affiche des informations. De sorte que le JRE est l'exportation localement. - L'ouverture de tous les ports dans le groupe de sécurité. Weeee.
- À l'aide de
tcpdump
assurez-vous que le trafic n'est pas d'aller vers d'autres ports. - Simuler localement. On peut toujours se connecter à notre local Jre ou ceux en cours d'exécution ailleurs sur notre réseau en utilisant les mêmes paramètres de l'application.
java -version
sorties:
OpenJDK Runtime Environment (IcedTea6 1.11.5) (amazon-53.1.11.5.47.amzn1-x86_64)
OpenJDK 64-Bit Server VM (build 20.0-b12, mixed mode)
En aparté, nous sommes à l'aide de mon Simple JMX package qui permet de les deux le RMI de registre et les ports du serveur qui sont généralement semi-aléatoirement choisi par le registre RMI. Vous pouvez également forcer avec quelque chose comme ce qui suit JMX URI:
service:jmx:rmi://localhost:" + serverPort + "/jndi/rmi://:" + registryPort + "/jmxrmi"
Ces jours, nous avons utiliser le même port pour le serveur et la base de registre. Dans le passé, nous avons utilisé X
que le registre-port et X+1
pour le serveur-port à la sécurité-règles de groupe facile. Vous vous connectez à la base de registre-port dans jconsole
ou quoi que client JMX vous utilisez.
Vous devez vous connecter pour publier un commentaire.
Il s'avère que le problème était dû à une combinaison de deux paramètres manquants. La première des forces de la JRE à préférer ipv4 et pas v6. Cela était nécessaire (je suppose) car nous essayons d'y connecter via un v4 adresse:
Le réel bloqueur a été le fait que JMX fonctionne d'abord en communiquant avec le RMI le port qui répond avec le nom d'hôte et le port du client JMX pour vous connecter. Avec pas de paramètres supplémentaires, il va utiliser l'adresse IP locale de la boîte qui est un
10.X.X.X
adresse virtuelle qui un client distant ne peut pas acheminer vers. Nous avions besoin d'ajouter le paramètre suivant qui est le externe nom d'hôte ou l'adresse IP du serveur -- dans ce cas, il est élastique, le nom d'hôte du serveur.Le truc, si vous essayez d'automatiser vos instances EC2 (et pourquoi diable voudriez-vous pas), est de savoir comment trouver cette adresse au moment de l'exécution. Pour cela vous avez besoin de mettre quelque chose comme ce qui suit dans notre application script de démarrage:
Le mystérieux
169.254.169.254
la propriété intellectuelle dans lewget
de commande ci-dessus fournit des informations que l'instance EC2 pouvez demander à propos de lui-même. Je suis déçu que ce ne pas inclure des balises qui ne sont disponibles que dans un appel authentifié.J'ai d'abord été à l'aide de la extern adresse ipv4 mais il semble que le JDK tente d'établir une connexion au serveur-port lorsqu'il démarre. Si il utilise l'adresse IP externe puis ce fut le ralentissement de notre temps de démarrage des applications jusqu'à ce que timed out. Le public-nom d'hôte décide localement à l'10 net de l'adresse et du public ipv4 à l'extérieur. Si l'application est maintenant de démarrage rapide et JMX clients encore du travail. Woo hoo!
Espère que cela aide quelqu'un d'autre. M'a coûté 3 heures aujourd'hui.
À la force de votre serveur JMX pour démarrer le serveur et le RMI registre sur les ports désignés de sorte que vous pouvez les bloquer dans les Groupes de Sécurité EC2, voir cette réponse:
Edit:
Nous avons juste eu ce problème se reproduise plus. Il semble que le Java JMX code est en train de faire quelque nom d'hôte des recherches sur le nom d'hôte de la boîte et de les utiliser pour essayer de se connecter et vérifier la connexion JMX.
Le problème semble être une exigence que le nom d'hôte local de la boîte doit se résoudre à local ip de la boîte. Par exemple, si votre
/etc/sysconfig/network
aHOSTNAME=server1.foobar.com
ensuite, si vous faites une recherche DNS surserver1.foobar.com
, vous devriez obtenir de l'10 NET d'adressage virtuel. Nous étions la génération de nos propres/etc/hosts
fichier et le nom d'hôte de l'hôte local était manquant dans le fichier. Cela a causé de nos applications de pause soit au démarrage ou pas de démarrage du tout.Enfin
Une façon de simplifier votre JMX création est d'utiliser mon SimpleJMX paquet.
key=value
type de choses donc, ops de ne pas faire une faute de frappe.java
avec-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=12345 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=ec2-X-X-X-X.compute-1.amazonaws.com -Djava.net.preferIPv4Stack=true
et je ne peux toujours pas me connecter à mon processus distant. J'ai simplifié le scénario d'une application simple qui affiche "Bonjour" toutes les 60 secondes par défaut d'Ubuntu AMI avec OpenJDK. Une idée du problème?netstat -lp
dans mon exemple j'ai pu voir que deux ports supplémentaires ont été ouverts par java. Je ne savais pas que j'avais besoin d'un de plus, je suppose que quand j'ai été le tester avant j'ai été le tester avec tous les ports ouverts pour moi... dumb moi. Il n'y a pas un non-programmatique façon (c'est à dire par le moyen des propriétés du système) pour définir ce second port, est-il? Si non, je suppose que je vais donner à votre SimpleJmx paquet d'essayer, alors!Par la deuxième réponse Pourquoi ne JMX connexion à Amazon EC2 échec?, la difficulté ici est que par défaut le port RMI est sélectionné au hasard, et les clients ont besoin d'accéder à la fois à l'JMX et RMI ports. Si vous êtes en cours d'exécution jdk7u4 ou plus tard, le port RMI peut être spécifié via une application. Démarrage de mon serveur avec les éléments suivants JMX paramètres fonctionné pour moi:
Sans authentification:
Avec authentification:
J'ai aussi ouvert les ports 9998-9999 dans le groupe de sécurité EC2 pour mon exemple.
Approche un peu différente en utilisant les tunnels ssh
-Dcom.sun.management.jmxremote.port=1099
-Djava.net.preferIPv4Stack=true
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
-Djava.rmi.server.hostname=127.0.0.1
netstat -tulpn | grep java
tcp 0 0 0.0.0.0:37484 0.0.0.0:* LISTEN 2904/java
tcp 0 0 0.0.0.0:1099 0.0.0.0:* LISTEN 2904/java
tcp 0 0 0.0.0.0:45828 0.0.0.0:* LISTEN 2904/java
ssh -N -L 1099:127.0.0.1:1099 ubuntu@<ec2_ip>
ssh -N -L 37484:127.0.0.1:37484 ubuntu@<ec2_ip>
ssh -N -L 45828:127.0.0.1:45828 ubuntu@<ec2_ip>
La réponse donnée par le Gris travaillé pour moi, cependant, je trouve que je dois ouvrir les ports TCP 0 à 65535 ou je ne suis pas dans la. Je pense que vous pouvez vous connecter sur le principal port JMX, et puis un autre attribué. J'ai reçu que de ce blog qui a toujours bien fonctionné pour moi.