Petals ESB n’est pas un load balancer !

A la base, cet article devrait expliquer l’utilisation de Petals ESB avec un load balancer en frontal du bus.
Le load balancer en question étant un serveur Apache avec le module « mod proxy balancer ». Mais finalement, il m’a semblé préférable de faire un billet intermédiaire pour expliquer ce qui n’est pas toujours évident à priori : Petals n’est pas un load balancer.

Petals ESB est composé de 3 principaux niveaux.

  • D’abord, il y  a le conteneur, que l’on appelle parfois abusivement le kernel. C’est le socle de l’infrastructure, qui assure le transport des messages, contient l’annuaire de services, gère le routage, conserve l’état des services, etc.
  • Ensuite, il y a les composants. Les composants se déploient sur le conteneur (cette relation conteneur – composants est définie dans la spécification JBI et est équivalente à ce qu’on peut trouver avec les EJB, OSGi ou SCA). Les composants fournissent une base de code réutilisable et configurable. Ils permettent d’implémenter la logique fonctionnelle.
  • Enfin, dernier niveau, ce sont les (fournisseurs de) services et les consommateurs de services. Ceux-ci sont créés sous la forme de configurations des composants. Cela permet d’implémenter des unités logiques et de les assembler pour répondre à des besoins fonctionnels.

Un service dans Petals est identifié par 3 composantes.

  • En premier lieu, il y a ce qu’on appelle le nom d’interface. Cela correspond à un contrat technique : à minima, on y trouve une liste d’opérations et les paramètres associés. Actuellement, un tel contrat se présente sous la forme d’un WSDL. Mais au-delà des aspects techniques, un contrat correspond aussi et surtout à une fonctionnalité, que l’on va pouvoir utiliser et invoquer dans son système d’information.
  • Vient ensuite le nom de service. Un service implémente une interface donnée. Dans la pratique, cette partie permet de distinguer des implémentations différentes. Par exemple, on pourrait avoir un contrat implémenté avec du Java (serviceJava) et avoir une autre implémentation en BPEL (serviceBpel). La fonctionnalité rendue serait la même, mais les propriétés seraient différentes (ici, il y en a un qui s’exécutera plus vite que l’autre). On pourrait aussi imaginer un cas plus métier. On peut imaginer avoir un contrat de réservation de voiture, et avoir une implémentation par société de location de voitures. Ce qui différencie alors les services, ce n’est pas la technologie d’implémentation mais le fournisseur.
  • Enfin, il y a le nom d’end-point. Cela correspond à un point de déploiement.

Un service déployé dans Petals possède toujours ces 3 parties.
La relation de cardinalité est la suivante :

interface 1 – * service(s) 1 – * end-point(s)

Autrement dit, à partir de l’annuaire de services du bus, on peut construire une hiérarchie.

Si on part de ce schéma, on aurait 6 services dans l’annuaire, identifiés par 6 triplets.

  1. Reservation Contrat / Res Service 1 / edpt 1
  2. Reservation Contrat / Res Service 1 / edpt 2
  3. Reservation Contrat / Res Service 2 / edpt 1
  4. Reservation Contrat / Res Service 3 / edpt 5
  5. Reservation Contrat / Res Service 3 / edpt 3
  6. Reservation Contrat / Res Service 3 / edpt 4

Dans Petals, du point de vue d’un consommateur, on peut utiliser cet arbre pour se donner de la flexibilité lors de l’invocation.

  • Cas explicite : le consommateur donne le triplet complet. On appellera donc ce service, qui implémente ce contrat, et qui est déployé au niveau de ce end-point.
  • Cas implicite : on invoque par nom d’interface et nom de service ou juste par nom d’interface. Dans ce cas, on va naviguer dans notre arbre et nous arrêter à un niveau intermédiaire plutôt qu’à une feuille. Le chemin restant (pour sélectionner un service concret) sera choisi par le bus. Par exemple, si l’on invoque juste par nom d’interface sur notre exemple, n’importe lequel des 6 services peut être choisi par le bus.

Pour une même interface, lorsque je trouve plusieurs services correspondants, j’ai une équivalence de services. Ils rendent la même fonctionnalité. Mais il peut y avoir des propriétés différentes : soit sur les performances, soit sur le domaine métier impliqué.

Pour un même service, lorsque je trouve plusieurs end-points correspondants, j’ai une réplication de services. C’est la même implémentation, le même service, la même interface, mais ce sont des points de déploiement différents, que l’on peut utiliser pour de la haute disponibilité.

Dans le cas d’une invocation implicite, c’est donc le bus qui sélectionne les informations manquantes (nom de service, nom d’end-point). Ce choix est actuellement basé sur des critères de proximité. Petals étant distribué, on va pouvoir privilégier des services proches du consommateur ou au contraire situés sur d’autres noeuds. Si après l’application de ce premier critère, il reste de multiples candidats, alors le bus choisira de manière aléatoire le service à invoquer. On pourrait bien sûr imaginer d’autres stratégies finales, par exemple basées sur la consommation des ressources, pour choisir le service susceptible de répondre le plus vite. Mais cela n’est pas implémenté pour le moment et il n’est pas prévu que ce soit fait à court terme.

Au final, cet article visait à souligner une chose.
Petals ESB sait faire du routage fonctionnel. Mais, ce n’est pas un load balancer. La nuance est très importante lorsque l’on conçoit une architecture avec Petals. Et autant, on pourrait enrichir le module de routage d’une stratégie avec équilibrage de charges (pour ce qui transite à l’intérieur du bus), autant cela ne suffirait pas pour les interactions avec des applications externes.

Publicités

About this entry