Vous aimez ce que vous lisez sur ce blog ?
Envie d'aller plus loin avec véritable formation d'expertise en Java ?
Venez suivre ma formation Masterclasse Expertise Java !

"Même un développeur experimenté a besoin de continuer à apprendre. Et dans cette formation... j'ai appris beaucoup !" - A.G., Java Champion

Prochaine sessions inter-entreprises : 13-16 février 2018
Sessions intra-entreprises sur demande : contact[at]mokatech.net.
Inscrivez-vous vite !

Clusteriser une application web avec TCServer et Terracotta

La majorité des applications produites de nos jours sont des applications web. Si leur conception et leur développement sont relativement bien maîtrisées, la mise en place de tests réalistes demeure trop souvent problématique en raison de la forte différence entre les environnements de développement et de production. En particulier, les problèmes de mise en cluster (load-balancing, réplication de session) et de montée en charge sont difficilement reproductibles localement.

Dans cet article, nous verrons comment utiliser TCServer et Terracotta pour mettre en place un mini-cluster de serveurs web en quelques minutes et déployer dessus une application simple avec réplication de sessions.

Notes préalables :

  • Les répertoires et commandes présentés ici correspondent à un environnement Linux. Adaptez-les si besoin à votre propre environnement.
  • L'étude de cas présentée ici utilise TCServer 6.0.19.A et Terracotta 3.0.1. Ces numéros de version peuvent apparaître dans des noms de répertoires ou de scripts. Adaptez-les au besoin.
  • TCServer et Terracotta ont la fâcheuse tendance à être abrégés en "TC" et à utiliser des variables d'environnement reprenant cette notation, ce qui peut entraîner des petits problèmes de lisibilité...

Présentation de l'application web

Pour cet article, nous utiliserons une application web très simple, consistant à incrémenter un compteur de visites placé en session. L'unique page JSP affiche la valeur courante du compteur.

Afin de gérer proprement la concurrence d'accès au compteur de visites, l'application utilise une variable de type AtomicInteger, qui offre une méthode getAndIncrement() garantie atomique :

  1. public class CounterServlet extends HttpServlet {
  2.  
  3. public static final String COUNTER_SESSION_ATTRIBUTE = "counter";
  4.  
  5. public void doGet(HttpServletRequest request, HttpServletResponse response)
  6. throws ServletException, IOException {
  7.  
  8. HttpSession session = request.getSession();
  9. AtomicInteger counter = (AtomicInteger) session.getAttribute(COUNTER_SESSION_ATTRIBUTE);
  10. int counterValue = counter.getAndIncrement();
  11.  
  12. request.setAttribute("counterValue", counterValue);
  13. RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/jsp/counter.jsp");
  14. dispatcher.forward(request, response);
  15. }
  16. }

Un SessionListener permet d'initialiser un nouveau compteur à chaque création de session, et de garantir sa présence avant l'appel de la servlet :

  1. public class CounterInitializerListener implements HttpSessionListener {
  2. public void sessionCreated(HttpSessionEvent event) {
  3. HttpSession session = event.getSession();
  4. session.setAttribute(CounterServlet.COUNTER_SESSION_ATTRIBUTE, new AtomicInteger(0));
  5. }
  6. }

Le but est évidemment de constater que le compteur s'incrémente de manière continue lorsque l'application est correctement clusterisée.

Déploiement de TC Server

Installation de TC Server

Commençons par installer le cluster de serveurs web.
Sur le site de TCServer, téléchargez l'archive correspondant à votre système d'exploitation puis décompressez-la dans un répertoire temporaire. Lancez le script "run.sh" et laissez-vous guider pour installer la SpringSource Application Management Suite (AMS) et/ou TCServer - pour cet article, nous nous contenterons de TCServer. Choisissez son répertoire d'installation, par exemple "/opt/Java/Tools/TCServer" ; cet emplacement sera appelé "<TC_INSTALL_DIR>" par la suite.

Pour éviter d'interférer avec une éventuelle installation préexistante de Tomcat sur votre machine, ajoutez la ligne suivante au début du script "<TC_INSTALL_DIR>/tcserver-ctl.sh" :

export CATALINA_HOME=<TC_INSTALL_DIR>/tomcat-6.0.19.A

Attention à bien remplacer "<TC_INSTALL_DIR>" par sa véritable valeur, et à adapter la version de Tomcat si nécessaire.

Création des instances

Nous allons maintenant créer deux instances de TCServer, qui formeront la base de notre mini cluster.
Ouvrez une console dans le répertoire "<TC_INSTALL_DIR>", puis invoquez le script "tcserver-instance.sh" avec les paramètres suivants :

  • -v : obligatoire, spécifie la version de TCServer. Adaptez-le en fonction de votre propre version.
  • -s : obligatoire, spécifie le nom de l'instance. Il est recommandé d'appliquer un pattern simple et cohérent.

Exemple :

  1. tcserver-instance.sh -v 6.0.19.A -s instance1
  2. tcserver-instance.sh -v 6.0.19.A -s instance2

Deux sous-répertoires "instance1" et "instance2" sont créés, contenant les éléments spécifiques aux instances (configuration, logs...). Le code binaire, commun, reste centralisé au niveau du répertoire "<TC_INSTALL_DIR>/tomcat-6.0.19.A/bin".

Configuration des instances

Il faut maintenant configurer les ports respectifs des instances (HTTP, JMX, etc.).
Sous Tomcat, cela nécessitait d'éditer le fichier "server.xml", ce qui pouvait se révéler fastidieux. TCServer étant prévu pour gérer de multiples instances quasi-identiques, leurs paramètres spécifiques sont astucieusement externalisés dans leurs fichiers "conf/catalina.properties".

Editez le fichier "conf/catalina.properties" de chaque instance pour régler ses ports.
Là encore, l'application d'un pattern d'attribution est recommandé, afin de faciliter la gestion des serveurs. Par exemple :

             Inst. 1   Inst. 2  ...  Inst. N
http.port    18081     18082         1808N 
jmx.port     18071     18072         1807N
ajp.port     18061     18062         1806N

Déploiement et test de l'application

Déploiement

Il est temps de déployer l'application de démonstration.

Tout d'abord, copiez le fichier "WebCounter.war" (disponible en pièce jointe de ce billet) dans le répertoire "webapps" des deux instances, puis démarrez-les grâce au script "<TC_INSTALL_DIR>/tcserver-ctl.sh" :

  1. tcserver-ctl.sh instance1 start
  2. tcserver-ctl.sh instance2 start

Vérifiez dans les logs que tout se passe bien.

Premier test de l'application

Testons maintenant notre installation.

Lancez votre navigateur web favori et accédez aux deux versions de l'application.
Si vous avez utilisé les réglages proposés ici, leurs adresses devraient être :

Rafraîchissez plusieurs fois la fenêtre de la première application : le compteur augmente, prouvant que la session HTTP utilisateur est active sur ce serveur.
Passez ensuite à la seconde application, et rafraîchissez-la également plusieurs fois. Le compteur repart de zéro puis est incrémenté, ce qui prouve que les sessions des deux versions de l'application sont indépendantes.

Nous allons maintenant activer la réplication automatique de session avec Terracotta, sans modifier l'application ni la configuration des instances.

Clusterisation avec Terracotta

Installation de Terracotta

Sur le site de Terracotta, téléchargez l'archive et décompressez-la dans un répertoire (par exemple "/opt/Java/Tools/Terracotta") que nous nommerons "<TERRACOTTA_INSTALL_DIR>".

Terracotta dispose de nombreux plugins facilitant la configuration des produits les plus courants, dont Tomcat. Leur gestion est confiée au script "<TERRACOTTA_INSTALL_DIR>/bin/tim-get.sh".
Tout d'abord, vérifiez la version courante du TIM Tomcat :

  1. tim-get.sh list

Puis installez-le grâce à la commande :

  1. tim-get.sh install tim-tomcat-6.0 1.1.0

Configuration des serveurs

Terracotta s'appuie sur un "Agent JVM" pour gérer la clusterisation des applications. Fonctionnant comme un plugin pour la JVM, il agit en instrumentant à la volée le code des classes, ce qui en fait une technologie totalement non-intrusive du point de vue applicatif.
L'agent Terracotta est activé en passant les options adéquates lors du démarrage des JVMs, grâce à la variable d'environnement "JAVA_OPTS".

Comme son ancêtre Tomcat, TCServer utilise le script "bin/setenv.sh" pour positionner diverses variables d'environnement avant de se lancer. Nous allons éditer ce script afin d'inclure les variables propres à Terracotta.
Editez le fichier "bin/setenv.sh" de chaque instance, et ajoutez-y les lignes suivantes :

export TC_INSTALL_DIR=<TERRACOTTA_INSTALL_DIR>
export TC_CONFIG_PATH=$TC_INSTALL_DIR/tc-config.xml
. $TC_INSTALL_DIR/bin/dso-env.sh -q
export JAVA_OPTS="$JAVA_OPTS $TC_JAVA_OPTS"

Ne relancez pas les serveurs tout de suite : il nous faut d'abord configurer et lancer le serveur Terracotta.

Configuration de Terracotta

Terracotta lui-même est paramétré via le fichier de configuration dont l'emplacement est indiqué par la variable d'environnement TC_CONFIG_PATH paramétrée plus haut. Ce fichier est généralement nommé "tc-config.xml" et placé à la racine du répertoire d'installation de Terracotta.
Il permet notamment de spécifier :

  • Le port sur lequel le serveur Terracotta tournera
  • Le répertoire contenant les données clusterisées
  • Le répertoire les logs
  • Les plugins spécifiques à activer (TIM ou Terracotta Integration Module)
  • Les données à clusteriser, et en particulier les applications web dont les sessions devront être répliquées

Voici le fichier de configuration activant la mise en cluster des sessions de notre application :

  1. <tc:tc-config xmlns:tc="http://www.terracotta.org/config"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://www.terracotta.org/schema/terracotta-4.xsd">
  4.  
  5. <servers>
  6. <server host="localhost">
  7. <dso-port>9510</dso-port>
  8. </server>
  9. </servers>
  10.  
  11. <clients>
  12. <modules>
  13. <module name="tim-tomcat-6.0" version="1.1.0"/>
  14. </modules>
  15. </clients>
  16.  
  17. <application>
  18. <dso>
  19. <web-applications>
  20. <web-application>WebCounter</web-application>
  21. </web-applications>
  22. </dso>
  23. </application>
  24.  
  25. </tc:tc-config>

Notez l'activation du module Tomcat téléchargé précédemment, et la déclaration de l'application web de démonstration.

Lancement du serveur Terracotta

Pour finir, lancez le serveur Terracotta à l'aide du script "<TERRACOTTA_INSTALL_DIR>/bin/start-tc-server.sh".

Test de l'application clusterisée

Il est temps de tester à nouveau le comportement de notre application.

Relancez les deux instances de TCServer, et exécutez les même tests que précédemment.
Si tout s'est bien déroulé, le compteur est maintenant incrémenté de manière continue quel que soit le serveur utilisé, prouvant que les sessions HTTP sont bien répliquées entre les serveurs.

Conclusion

Si l'on excepte la phase d'installation des produits, nous constatons qu'il est très simple de mettre en place un mini-cluster web sur une machine de développement, et d'y déployer une application web aux sessions clusterisées.


Commentaires

1. Le mardi 3 mai 2011, 09:50 par ugo

Bonjour Olivier,
Je reprends ce tuto actuellement et je n'arrive pas à répliquer les sessions http de mes deux serveurs.
Je suis sur un environnement windows et j'utilise une version plus récente de terracotta (3.5.1) et de tc-server(6.0.32.B.RELEASE) donc j'ai du adapter quelques conf par rapport à ton billets.
Mais manifestement la session n'est pas partagée entre les deux serveurs.
Je n'arrive pas non plus à récupérer de log d'erreur montrant une erreur dans les confs.
Aurais-tu une idée d'une raison possible de mon échec ?
Je ne sais pas si c'est le bon endroit pour poser ce genre de question. Mes excuses par avance si ce n'est pas la cas.

2. Le mercredi 4 mai 2011, 16:31 par ugo

Bonjour Olivier,
Ya-t-il une conf particulière à ajouter côté client ou serveur si les clients et le serveur terracotta ne sont pas sur la même machine ?
J'ai vu sur la doc terracotta que le variable TC_CONFIG_PATH devenait TC_CONFIG_PATH=<server_host>:<dso-port> mais je ne sais pas quoi faire des autres variables de mon script setenv.sh ni s'il faut rajouter d'autres conf.

3. Le mardi 10 mai 2011, 15:27 par ugo

Je lis la doc terracotta et je m'aperçois que pour pourvoir installer un cluster de serveur terracotta il faut acheter la version entreprise edition du logiciel.
Est-ce que je me gourre ?

4. Le mardi 10 mai 2011, 20:38 par Olivier Croisier

Non, c'est bien ça.
C'est la limite entre la version gratuite et la payante : le clustering des serveurs Terracotta, le support, et le Book of Operations (bible pour les admins).

Attention on parle bien de cluster des *serveurs* Terracotta : pour mettre en cluster des *applications*, c'est gratuit.

Ajouter un commentaire

Le code HTML est affiché comme du texte et les adresses web sont automatiquement transformées.