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

Sessions intra-entreprises sur demande : contact[at]mokatech.net.
Inscrivez-vous vite !

Terracotta, ou le clustering de session pour les nuls

Dans un récent article intitulé "Terracotta, un an après", je vous décrivais la volonté de Terracotta de simplifier la mise en oeuvre du framework sur ses principaux cas d'utilisation : clustering de sessions HTTP, clustering de cache EHCache ou Hibernate, intégration avec Spring et Quartz...
Peu à peu apparaissent donc des solutions packagées et pré-configurées, reconnaissables à leur suffixe "Express".

Si vous suivez ce blog, vous savez déjà clusteriser des sessions HTTP avec Terracotta et TCServer, en configurant manuellement la plateforme ; aujourd'hui, je vous parlerai du module "HTTP Session Clustering Express", introduit avec Terracotta 3.2.1-beta, qui simplifie nettement le processus.

Standard ou Express ?

Mais avant de se lancer dans le code, il est nécessaire de comprendre les avantages et inconvénients des deux solutions.

  • Dans la solution traditionnelle, les sessions HTTP et leurs attributs sont instrumentés et surveillés par Terracotta, grâce à un bootjar chargé au démarrage de la JVM. Grâce à cette instrumentation, Terracotta est alors capable de détecter et répercuter le moindre changement sur les champs de ces objets.
    Cette granularité ultra-fine offre des performances maximales, et ne nécessite pas que les objets répliqués soient Serializable. En revanche, la configuration de la plateforme peut se révéler complexe (il faut notamment déclarer manuellement les classes à instrumenter), et le bootjar n'est pas portable sur toutes les JVMs.
  • La version Express, au contraire, s'appuie au contraire sur des mécanismes comme des filtres de servlets (Jetty, Weblogic) ou des Valves (Tomcat, JBoss) pour détecter les changements et les transmettre au serveur terracotta, et sont livrés sous la forme d'un simple Jar à intégrer sur les serveurs d'application.
    L'avantage de cette solution est évidemment sa simplicité de mise en oeuvre et sa portabilité inter-JVM. L'inconvénient, c'est que la réplication se base désormais sur le mécanisme de sérialisation standard de Java, nettement moins performant, et qui nécessite que les objets manipulés implémentent Serializable. De plus, la configuration diffère légèrement d'un serveur d'application à l'autre.

A vous de choisir la solution la plus adaptée à votre projet, sachant qu'il n'est pas forcément indolore de passer de l'une à l'autre...



Mise en place de la plateforme de test

Présentation de l'application

L'application que nous utiliserons est disponible en annexe de ce billet.

Elle est fort simple : à chaque rafraîchissement de son unique page, un compteur de visites est incrémenté et affiché.
Comme la version Express du module de clustering HTTP se base sur l'interception des méthodes de HttpSession (setAttribute(), removeAttribute()...) pour détecter et répercuter les modifications apportées aux sessions, il est nécessaire de réassocier le compteur à la session après chaque incrémentation - c'est l'une des quelques différences subtiles avec la version standard.

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

Le compteur est initialisé à 0 lors du démarrage de l'application, à l'aide d'un Listener.

  1. public class CounterInitializerListener implements HttpSessionListener {
  2.  
  3. public void sessionCreated(HttpSessionEvent event) {
  4. HttpSession session = event.getSession();
  5. session.setAttribute(CounterServlet.COUNTER_SESSION_ATTRIBUTE, 0);
  6. }
  7.  
  8. public void sessionDestroyed(HttpSessionEvent event) {
  9. }
  10.  
  11. }

Installation de TCServer

Pour l'installation de TCServer et la configuration de deux instances, je vous laisse vous reporter à l'article "Clusteriser une application web avec Terracotta et TCServer".

Dans la suite de l'article, nous considèrerons que TCServer est installé dans le répertoire <TCSERVER_INSTALL_DIR> et que les deux instances écoutent respectivement sur les ports 8081 et 8082.

Installation de Terracotta

Pour le moment, Terracotta 3.2.1-beta n'est disponible que sur inscription, mais les fonctionnalités évoquées ici seront sans doute bientôt disponibles dans la prochaine version publique.

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



Configuration

Configuration du serveur Terracotta

Le mode Express porte bien son nom : pour les cas simples, aucune configuration spécifique n'est nécessaire sur le serveur Terracotta !
Vous pourriez donc le lancer immédiatement avec ses paramètres par défaut :

  1. <TERRACOTTA_INSTALL_DIR>/bin/start-tc-server.sh &
  2. Ex: /opt/Java/Tools/Terracotta/bin/start-tc-server.sh &

Toutefois, c'est une bonne pratique de redéfinir au moins les répertoires contenant les données et les logs.
Créez un fichier "tc-config.xml" dans le répertoire "<TERRACOTTA_INSTALL_DIR>", et choisissez où placer les données et les logs :

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <tc:tc-config xmlns:tc="http://www.terracotta.org/config"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.terracotta.org/schema/terracotta-5.xsd">
  5.  
  6. <servers>
  7. <server>
  8. <data>/home/olivier/Java/Tools/Terracotta/data</data>
  9. <logs>/home/olivier/Java/Tools/Terracotta/logs/server</logs>
  10. <dso-port>9510</dso-port>
  11. </server>
  12. </servers>
  13.  
  14. <clients>
  15. <!-- Le %i représente l'IP des clients connectés -->
  16. <logs>/home/olivier/Java/Tools/Terracotta/logs/clients/%i</logs>
  17. </clients>
  18.  
  19. </tc:tc-config>

Il suffit alors d'indiquer l'emplacement de ce fichier au serveur Terracotta :

  1. <TERRACOTTA_INSTALL_DIR>/bin/start-tc-server.sh -f <TERRACOTTA_INSTALL_DIR>/tc-config.xml
  2. Ex : /opt/Java/Tools/Terracotta/bin/start-tc-server.sh -f /opt/Java/Tools/Terracotta/tc-config.xml

Pour vérifier que le serveur est bien démarré, utilisez la console d'administration de Terracotta :

  1. <TERRACOTTA_INSTALL_DIR>/bin/dev-console.sh &
  2. Ex: /opt/Java/Tools/Terracotta/bin/dev-console.sh &

DevConsole1.png

Configuration de l'application et de TCServer

Comme indiqué plus haut, la configuration du module HttpSessions Clustering Express dépend du serveur d'application utilisé - dans notre cas, TCServer se configure comme Tomcat, dont il est dérivé.

La configuration est effectivement très simple. Il suffit de :

  • Copier le jar <TERRACOTTA_INSTALL_DIR>/sessions/terracotta-session-1.0.0-SNAPSHOT.jar dans le répertoire <TCSERVER_INSTALL_DIR>/tomcat-<version>/lib.
  • Déclarer la Valve appropriée dans le fichier /META-INF/context.xml de notre application :
  1. <Context>
  2. <Valve className="org.terracotta.session.TerracottaTomcat60xSessionValve" tcConfigUrl="localhost:9510" />
  3. </Context>

Notez que c'est dans la "valve" que l'on configure le serveur Terracotta auquel l'application sera connectée - ici, notre serveur local, sur le port par défaut 9510.

Pour finir, démarrez les deux instances de TCServer, et déployez l'application dessus.
La console d'administration de Terracotta devrait alors signaler que deux clients se sont connectés au serveur :

DevConsole2.png

Test du clustering

Dans un navigateur, ouvrez un onglet sur chaque serveur :

Rafraîchissez un onglet plusieurs fois pour voir le compteur de visites s'incrémenter.
Maintenant, passez sur le second onglet et rafraîchissez-le. Le compteur devrait continuer à s'incrémenter à partir de la valeur atteinte sur le premier onglet, prouvant que les sessions HTTP des deux serveurs ont été synchronisées par Terracotta. Félicitations !

Conclusion

Nous avons vu au cours de cet article que la mise en cluster de sessions HTTP avec Terracotta était relativement simple, en utilisant le module HTTP Sessions Clustering Express : très peu de configuration côté serveur, un simple jar sur le serveur d'applications, et la déclaration d'une "valve" au niveau de l'application.
Mais cette simplicité vient au prix d'une perte notable en performances par rapport à la version "standard", à cause de l'utilisation de la sérialisation Java...

En tant qu'architecte, ma préférence reste au mode de configuration standard, qui me permet de tirer toute la puissance de la plateforme Terracotta, et qui ne me lie pas à un serveur d'applications particulier. Mais pour tester rapidement une application à grande échelle, notamment pour détecter des problèmes d'accès concurrents, le déploiement de la version Express est une option séduisante, surtout sur TCServer qui permet de créer instantanément un cluster de serveurs.

Vous trouverez en annexe de ce billet une archive "war" immédiatement déployable, qui contient également le code source de l'application.


Ajouter un commentaire

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