Clustering J2EE, partie 1

Les entreprises choisissent Java 2, Enterprise Edition (J2EE) pour fournir leurs applications critiques sur le Web. Dans le cadre J2EE, les clusters fournissent des services critiques pour garantir un temps d'arrêt minimal et une évolutivité maximale. Un cluster est un groupe de serveurs d'applications qui exécutent de manière transparente votre application J2EE comme s'il s'agissait d'une seule entité. Pour évoluer, vous devez inclure des machines supplémentaires dans le cluster. Pour minimiser les temps d'arrêt, assurez-vous que chaque composant du cluster est redondant.

Dans cet article, nous allons acquérir une compréhension de base du clustering, des méthodes de clustering et des services de cluster importants. Étant donné que les approches de regroupement varient d'un secteur à l'autre, nous examinerons les avantages et les inconvénients de chaque approche. En outre, nous discuterons des fonctionnalités importantes liées au cluster à rechercher dans un serveur d'applications.

Pour appliquer nos nouvelles connaissances en clustering au monde réel, nous verrons comment HP Bluestone Total-e-Server 7.2.1, Sybase Enterprise Application Server 3.6, SilverStream Application Server 3.7 et BEA WebLogic Server 6.0 implémentent chacun des clusters.

Dans la deuxième partie de cette série, nous aborderons les stratégies de programmation et de basculement pour les clusters, ainsi que les tests de nos quatre produits de serveur d'applications pour voir comment ils évoluent et basculent.

Clusters définis

Les fournisseurs de serveurs d'applications J2EE définissent un cluster comme un groupe de machines travaillant ensemble pour fournir de manière transparente des services d'entreprise (prise en charge de JNDI, EJB, JSP, HttpSession et le basculement de composants, etc.). Ils laissent la définition volontairement vague car chaque fournisseur implémente le clustering différemment. À une extrémité du spectre se trouvent des fournisseurs qui placent un répartiteur devant un groupe de machines indépendantes, dont aucune n'a connaissance des autres machines du cluster. Dans ce schéma, le répartiteur reçoit une demande initiale d'un utilisateur et répond avec un en-tête de redirection HTTP pour épingler le client à un serveur membre particulier du cluster. À l'autre extrémité du spectre résident des fournisseurs qui mettent en œuvre une fédération de machines étroitement intégrées,avec chaque machine totalement consciente des autres machines autour d'elle avec les objets sur ces machines.

En plus des machines, les clusters peuvent comprendre des éléments redondants et capables de basculer:

  • Équilibreurs de charge: points d'entrée uniques dans le cluster et directeurs de trafic vers des serveurs Web ou d'applications individuels
  • Serveurs Web
  • Routeurs de passerelle: points de sortie hors d'un réseau interne
  • Commutateurs multicouches: filtres de paquets et de trames pour garantir que chaque machine du cluster ne reçoive que les informations pertinentes pour cette machine
  • Pare-feu: protège les clusters contre les pirates en filtrant l'accès au niveau du port au cluster et au réseau interne
  • Commutateurs SAN (Storage Area Networking): connectez les serveurs d'applications, les serveurs Web et les bases de données à un support de stockage principal; gérer le disque physique sur lequel écrire les données; et basculement
  • Bases de données

Quelle que soit la manière dont ils sont mis en œuvre, tous les clusters offrent deux avantages principaux: l' évolutivité et la haute disponibilité (HA).

Évolutivité

L'évolutivité fait référence à la capacité d'une application à prendre en charge un nombre croissant d'utilisateurs. Les clusters vous permettent de fournir une capacité supplémentaire en ajoutant des serveurs supplémentaires, garantissant ainsi l'évolutivité.

La haute disponibilité

HA peut se résumer en un mot: redondance. Un cluster utilise de nombreuses machines pour traiter les demandes. Par conséquent, si une machine d'un cluster tombe en panne, une autre machine peut prendre le relais de manière transparente.

Un cluster fournit uniquement la haute disponibilité au niveau du serveur d'applications. Pour qu'un système Web présente une véritable haute disponibilité, il doit être comme l'arche de Noé en contenant au moins deux de tout, y compris des serveurs Web, des routeurs de passerelle, des infrastructures de commutation, etc. (Pour plus d'informations sur HA, consultez la liste de contrôle HA.)

Types de cluster

Les clusters J2EE se déclinent généralement en deux versions: rien partagé et disque partagé. Dans un cluster sans partage, chaque serveur d'applications possède ses propres systèmes de fichiers avec sa propre copie des applications exécutées dans le cluster. Les mises à jour et les améliorations des applications nécessitent des mises à jour dans chaque nœud du cluster. Avec cette configuration, les grands clusters deviennent des cauchemars de maintenance lorsque le code pousse et que les mises à jour sont publiées.

En revanche, un cluster de disques partagés utilise un seul périphérique de stockage que tous les serveurs d'applications utilisent pour obtenir les applications exécutées dans le cluster. Les mises à jour et les améliorations se produisent dans un seul système de fichiers et toutes les machines du cluster peuvent accéder aux modifications. Jusqu'à récemment, l'un des inconvénients de cette approche était son point de défaillance unique. Cependant, SAN fournit une interface logique unique dans un support de stockage redondant pour assurer le basculement, la restauration et l'évolutivité. (Pour plus d'informations sur le SAN, consultez la barre latérale Infrastructure de stockage.)

Lors de la comparaison des implémentations de cluster des serveurs d'applications J2EE, il est important de prendre en compte:

  • Implémentation de cluster
  • Services de basculement de cluster et de composant
  • Basculement HttpSession
  • Points de défaillance uniques dans une topologie de cluster
  • Disposition de la topologie flexible
  • Entretien

Plus tard, nous verrons comment quatre serveurs d'applications populaires se comparent dans divers domaines. Mais d'abord, examinons chaque élément plus en détail.

Implémentation de cluster

Les serveurs d'applications J2EE implémentent le clustering autour de leur implémentation de JNDI (Java Naming and Directory Interface). Bien que JNDI soit le service principal sur lequel reposent les applications J2EE, il est difficile à implémenter dans un cluster car il ne peut pas lier plusieurs objets à un seul nom. Trois méthodes générales de clustering existent en relation avec l'implémentation JNDI de chaque serveur d'applications:

  • Indépendant
  • Centralisé
  • Global partagé

Arborescence JNDI indépendante

HP Bluestone Total-e-Server et SilverStream Application Server utilisent une arborescence JNDI indépendante pour chaque serveur d'applications. Les serveurs membres d'un cluster d'arborescence JNDI indépendant ne connaissent pas ou ne se soucient pas de l'existence d'autres serveurs dans le cluster. Par conséquent, le basculement n'est pas pris en charge ou fourni via des services intermédiaires qui redirigent les requêtes HTTP ou EJB. Ces services intermédiaires sont configurés pour savoir où réside chaque composant du cluster et comment accéder à un autre composant en cas de panne.

Un avantage du cluster d'arborescence JNDI indépendant: une convergence de cluster plus courte et une facilité de mise à l'échelle. La convergence du cluster mesure le temps nécessaire au cluster pour prendre pleinement conscience de toutes les machines du cluster et de leurs objets associés. Cependant, la convergence n'est pas un problème dans un cluster d'arborescence JNDI indépendant car le cluster réalise la convergence dès que deux machines démarrent. Autre avantage du cluster d'arborescence JNDI indépendant: la mise à l'échelle ne nécessite que l'ajout de serveurs supplémentaires.

Cependant, plusieurs faiblesses existent. Premièrement, le basculement est généralement la responsabilité du développeur. En d'autres termes, comme l'arborescence JNDI de chaque serveur d'applications est indépendante, les proxys distants récupérés via JNDI sont épinglés sur le serveur sur lequel la recherche a eu lieu. Dans ce scénario, si un appel de méthode à un EJB échoue, le développeur doit écrire du code supplémentaire pour se connecter à un répartiteur, obtenir l'adresse d'un autre serveur actif, effectuer une autre recherche JNDI et appeler à nouveau la méthode ayant échoué. Bluestone implémente une forme plus compliquée de l'arborescence JNDI indépendante en faisant passer chaque requête via un service proxy EJB ou Proxy LBB (Load Balance Broker). Le service proxy EJB garantit que chaque requête EJB est dirigée vers une instance UBS active. Ce schéma ajoute une latence supplémentaire à chaque requête mais permet un basculement automatique entre les appels de méthode.

Arborescence JNDI centralisée

Sybase Enterprise Application Server implémente un cluster d'arborescence JNDI centralisé. Dans cette configuration, les clusters d'arbres JNDI centralisés utilisent le service CosNaming de CORBA pour JNDI. Les serveurs de noms hébergent l'arborescence JNDI centralisée du cluster et gardent une trace des serveurs actifs. Au démarrage, chaque serveur du cluster lie ses objets dans son arborescence JNDI ainsi que tous les serveurs de noms.

L'obtention d'une référence à un EJB dans un cluster d'arborescence JNDI centralisé est un processus en deux étapes. Tout d'abord, le client recherche un objet home à partir d'un serveur de noms, qui renvoie une référence d'objet interopérable (IOR). Un IOR pointe vers plusieurs machines actives du cluster qui ont l'objet home. Deuxièmement, le client choisit le premier emplacement de serveur dans l'IOR et obtient le domicile et le distant. En cas d'échec entre les appels de méthode EJB, le stub CORBA implémente une logique pour récupérer un autre domicile ou un autre serveur distant d'un autre serveur répertorié dans l'IOR renvoyé par le serveur de noms.

Les serveurs de noms eux-mêmes démontrent une faiblesse du cluster d'arborescence JNDI centralisé. Plus précisément, si vous avez un cluster de 50 machines, dont cinq sont des serveurs de noms, le cluster devient inutile si les cinq serveurs de noms tombent en panne. En effet, les 45 autres machines pourraient être opérationnelles mais le cluster ne servira pas un seul client EJB tant que les serveurs de nommage sont en panne.

Un autre problème provient de la mise en ligne d'un serveur de noms supplémentaire en cas de panne totale des serveurs de noms d'origine du cluster. Dans ce cas, un nouveau serveur de noms centralisé nécessite que chaque machine active du cluster lie ses objets dans l'arborescence JNDI du nouveau serveur de noms. Bien qu'il soit possible de commencer à recevoir des demandes pendant le processus de liaison, cela n'est pas recommandé, car le processus de liaison prolonge le temps de récupération du cluster. De plus, chaque recherche JNDI à partir d'une application ou d'une applet représente en réalité deux appels réseau. Le premier appel récupère l'IOR d'un objet à partir du serveur de noms, tandis que le second récupère l'objet souhaité par le client sur un serveur spécifié dans l'IOR.

Enfin, les clusters d'arbres JNDI centralisés souffrent d'un temps de convergence accru à mesure que le cluster augmente en taille. Autrement dit, lorsque vous mettez à l'échelle votre cluster, vous devez ajouter d'autres serveurs de noms. Gardez à l'esprit que le rapport généralement accepté entre les machines de serveurs de noms et le nombre total de machines en cluster est de 1:10, avec un nombre minimum de deux serveurs de noms. Par conséquent, si vous disposez d'un cluster de 10 ordinateurs avec deux serveurs de noms, le nombre total de liaisons entre un serveur et un serveur de noms est de 20. Dans un cluster de 40 ordinateurs avec quatre serveurs de noms, il y aura 160 liaisons. Chaque liaison représente un processus dans lequel un serveur membre lie tous ses objets dans l'arborescence JNDI d'un serveur de noms. Dans cet esprit, le cluster d'arborescence JNDI centralisé a le pire temps de convergence parmi toutes les implémentations de cluster JNDI.

Arborescence JNDI globale partagée

Enfin, BEA WebLogic implémente une arborescence JNDI globale partagée. Avec cette approche, lorsqu'un serveur du cluster démarre, il annonce son existence et son arborescence JNDI aux autres serveurs du cluster via la multidiffusion IP (Internet Protocol). Chaque machine en cluster lie ses objets dans l'arborescence JNDI globale partagée ainsi que dans sa propre arborescence JNDI locale.

Le fait d'avoir une arborescence JNDI globale et locale dans chaque serveur membre permet aux stubs domestiques et distants générés de basculer et fournit des recherches JNDI rapides en cours de processus. L'arborescence JNDI globale partagée est partagée entre toutes les machines du cluster, permettant à toute machine membre de connaître l'emplacement exact de tous les objets du cluster. Si un objet est disponible sur plusieurs serveurs du cluster, un objet d'accueil spécial est lié dans l'arborescence JNDI globale partagée. Ce foyer spécial connaît l'emplacement de tous les objets EJB auxquels il est associé et génère des objets distants qui connaissent également l'emplacement de tous les objets EJB auxquels il est associé.

Les inconvénients majeurs de l'approche globale partagée: l'important trafic réseau initial généré au démarrage des serveurs et le long temps de convergence du cluster. En revanche, dans un cluster d'arborescence JNDI indépendant, la convergence s'avère ne pas être un problème car aucun partage d'informations JNDI ne se produit. Cependant, un cluster global ou centralisé partagé nécessite du temps pour que toutes les machines du cluster construisent l'arborescence JNDI globale ou centralisée partagée. En effet, comme les clusters globaux partagés utilisent la multidiffusion pour transférer les informations JNDI, le temps nécessaire pour construire l'arborescence JNDI globale partagée est linéaire par rapport au nombre de serveurs ajoutés ultérieurement.

Les principaux avantages du partage global par rapport aux clusters d'arbres JNDI centralisés sont centrés sur la facilité de mise à l'échelle et une meilleure disponibilité. Avec shared global, vous n'avez pas à jouer avec les processeurs et la RAM sur un serveur de noms dédié ou à régler le nombre de serveurs de noms dans le cluster. Pour faire évoluer l'application, ajoutez simplement plus de machines. De plus, si une machine du cluster tombe en panne, le cluster continuera à fonctionner correctement. Enfin, chaque recherche à distance nécessite un seul appel réseau par rapport aux deux appels réseau requis dans le cluster d'arborescence JNDI centralisé.

Tout cela doit être pris avec un grain de sel car les JSP, les servlets, les EJB et les JavaBeans exécutés sur le serveur d'applications peuvent profiter de la co-implantation dans le serveur EJB. Ils utiliseront toujours une recherche JNDI en cours. Gardez à l'esprit que si vous exécutez uniquement des applications côté serveur, il existe peu de différence entre les implémentations de cluster globales indépendantes, centralisées ou partagées. En effet, chaque requête HTTP aboutira sur un serveur d'application qui effectuera une recherche JNDI en cours pour renvoyer tout objet utilisé dans votre application côté serveur.

Ensuite, nous tournons notre attention vers la deuxième considération importante du serveur d'applications J2EE: les services de cluster et de basculement.

Services de cluster et de basculement