Guillaume VIEL :: java jee tomcat linux

Aller au contenu | Aller au menu | Aller à la recherche

jeudi 20 mars 2008

Monitoring JVM Tomcat 5 avec jconsole, tunnel SSH et firewall...

Dans billet du 16 mars je présentais un monitoring java avec VisualGC. En réalité, cela n'était qu'une mise en bouche par rapport à ce qui suit... En effet, jconsole, l'outil fournit en standard dans le JDK Sun a aussi tout ce qu'il faut pour réaliser un monitoring Java. Il n'est disponible qu'à partir de java 5.
En fait jconsole est utile en phase de développement. Pour un monitoring persistent, il faudra plutôt s'orienter vers des solutions comme Munin par exemple qui permet une collecte et historisation des données dans le temps, avec surtout le stockage de ces données. Toutes les données jconsole sont perdues lors de l'arrêt de la JVM. Je vais présenter ici un nième exemple de monitoring de Tomcat par jconsole en connexion non sécurisée, Dans l'entête de votre bin/catalina.sh mettez ceci (les lignes en commentaire correspondent justement à celle qui seraient susceptibles de faire marcher le SSL) :

JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote"
JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote.authenticate=false"
JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote.port=8889"
JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote.ssl=false" echo $JAVA_OPTS

jmxremote.authenticate=false : permet d'indiquer que l'on ne veut pas utiliser le fichier de password (jmxremote.password.file)
jmxremote.port=8889 : indique le port sur lequel on va se connecter avec jconsole
jmxremote.ssl=false : désactive le SSL

Ensuite, sur un client disposant d'un JDK on peut lancer jconsole comme suit :
$ jconsole mytomcathost:8889 &


Je lance un appel à ceux ou celles qui auraient réussi une connexion remote en SSL entre jconsole et le serveur à monitorer, car, oui, je l'avoue, mes nombreux essais en suivant scrupuleusement la doc Sun, que ce soit sous linux, voire sous windows (si! si! je passe de temps à autre sous cet OS...), n'ont jamais abouti! Et après de nombreuses recherches, aucun article sur internet ne semble présenter une solution qui fonctionne avec SSL. Si vous avez la solution je suis preneur : envoyez moi l'article! Les lignes suivantes seraient à ajouter :

#JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote.password.file=/home/tomcat/jmxremote.password"
#JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote.ssl.need.client.auth=true"
#JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.keyStore=/home/tomcat/.keystore"
#JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.keyStorePassword=changeit"

* UPDATE 15/11/2008 : aurais-je oublié ceci : com.sun.management.jmxremote.registry.ssl=true ??? *

Pour contourner ce problème ainsi que la lourdeur de mise en oeuvre d'une connexion SSL (génération des certificats), on peut utiliser sur une plateforme de type linux d'autres outils qui peuvent prendre en charge la sécurité. Parmi les alternatives possibles, seul le tunneling SSH (avec échange de la clé publique vers le serveur cible) pourra fonctionner, moyennant quelques manipulations manuelles supplémentaires. Car en réalité, ceci n'est pas aussi simple qu'il n'y parait. Si l'on exécute les commandes suivantes sur la machine client :

ssh -L18889:localhost:8889 my.remote.tomcat.host
jconsole localhost:18889

on s'aperçoit en fait que cela ne fonctionne pas... Eh oui : côté serveur 2 ports supplémentaires aléatoires de valeur N et N+1 sont en écoute pour le RMI registry en plus du port jmxremote.port :

$ netstat -tlnp | grep java
tcp6 0 0 ::ffff:127.0.0.1:8006 :::* LISTEN 5374/java
tcp6 0 0 :::8889 :::* LISTEN 5374/java
tcp6 0 0 :::8009 :::* LISTEN 5374/java
tcp6 0 0 :::8080 :::* LISTEN 5374/java
tcp6 0 0 :::40882 :::* LISTEN 5374/java
tcp6 0 0 :::40883 :::* LISTEN 5374/java

jconsole essaye alors de se connecter sur les ports N=40882 et N+1 en localhost sur la machine cliente alors qu'il accède bien grâce à SSH par port forwarding au port 8889! Si vous êtes pressé, la solution consiste à créer 2 tunnels SSH supplémentaires vers ces ports :

ssh -L40882:localhost:40882 my.remote.tomcat.host
ssh -L40883:localhost:40883 my.remote.tomcat.host

Cette méthode n'est pas très "propre", nécessite des opérations manuelles pour trouver les ports dynamiques dès que vous redémarrez votre serveur et ne fonctionnera pas dans un environnement avec certaine configuration de firewall (il faut aussi ajouter -Djava.rmi.server.hostname=localhost au niveau serveur)...

J'ai finalement trouvé sur un des blogs Sun un article intéressant à ce sujet : Connecting Through Firewall Using JMX - Without modifying the server application

Dans cet article Daniel Fuchs explique comment créer son propre JVM agent auquel on pourra passer en option un port fixe.

Liens : Monitoring and Management Using JMX | Monitoring Applications through a Firewall | Keytool documentation

mardi 18 mars 2008

Monitoring JVM Sun avec jvmstat et VisualGC

Sun propose quelques outils pour monitorer la JVM : jstatd, jvmstat et visualGC. Cela reste rudimentaire par rapport à d'autres outils comme jconsole mais cela a le mérite d'exister! Le principal intérêt d'utiliser encore cet outil est qu'il fonctionne pour les vieilles JVM version 1.4! Cet outil n'est pas packagé directement dans le JDK. Voici comment mettre en place cette techno rapidement en Java 1.4, Java 5 ou Java 6 entre une machine linux sur laquelle réside l'application java à monitorer et un poste de travail windows ou linux

Lire la suite...