23 février 2010
Imprimer ce billet

AMQP, une alternative à JMS ?

Vous avez une application Java qui doit envoyer et recevoir des messages à droite et à gauche pour des raisons qui n’appartiennent qu’à vous… Votre premier réflexe sera sûrement de contacter votre vieil ami JMS. Pour ça, vous aurez aussi besoin d’un broker de message, mais vous n’êtes pas très riche et des outils comme WebSphere ou Tibco sont hors de portée… Vous aurez alors de fortes chances de vous tourner vers votre autre vieil ami ActiveMQ. Bon d’accord, l’amitié ça compte, mais par ailleurs d’autres amis (des vrais !) vous signalent qu’ils ont eu quelques problèmes de blocage de file avec ActiveMQ et qu’ils ont eu du mal à identifier ces problèmes. En plus vous avez encore d’autres amis qui aimeraient bien communiquer avec vous sur ce même broker mais leurs applications tournent en ruby et C++ qui parlent mal le JMS… C’est le moment idéal de vous présenter un nouvel ami : AMQP !

AMQP (Advanced Message Queuing Protocol) est un protocole de messagerie créé à l’initiative de la banque JP Morgan Chase pour gérer la communication entre ses différents partenaires. Le but affiché était de fournir une solution alternative aux solutions payantes et relativement chères dans le domaine du MOM (Message-Oriented Middleware) dominé largement par Websphere MQ d’IBM et RendezVous de Tibco (93% du marché à eux deux en 2008). Un certain nombre de partenaires se sont fédérés autour de ce projet pour aboutir à une première spécification en 2006. L’ambition avouée est qu’elle devienne l’équivalent du HTTP pour l’internet, ce qui explique qu’elle décrive aussi bien les différentes sémantiques liées au MOM que la partie plus bas niveau du transport de ces messages. Cette normalisation permet la multiplication des solutions clientes ou serveurs dont la compatibilité sera garantie par cette spécification. Par exemple, un broker de message écrit en Erlang comme RabbitMQ transférera de façon transparente un message d’un client ruby vers un autre client Java/JMS.

Notez bien qu’AMQP s’identifie clairement comme un protocole et non comme une API, contrairement à JMS. Donc un client Java basé sur JMS peut, moyennant des adaptations plus ou moins coûteuses, communiquer avec un broker AMQP.

Un nouveau protocole

Les spécifications AMQP sont parties de cas d’utilisation très concrets pour aboutir à des spécifications essayant d’englober un maximum de typologies. Voici quelques unes d’entre elles (QPid ou RabbitMQ) :

  • Store-and-forward: les messages sont persistés puis récupérés par un seul client qui décidera s’il faut les supprimer.
  • Point-to-point: une communication dédiée entre un émetteur et un receveur, éventuellement bidirectionnelle.
  • One-to-many (ou fanout): un message est retransmis à toutes les queues d’une zone d’échange. Ceci permet de modéliser le multicast.
  • Transaction (distribuée ou pas): l’émetteur peut englober un paquet de messages dans une transaction, ces messages ne pourront être lus que lorsque l’émetteur les aura acquittés.
  • Publish-subscribe (pub-sub): plusieurs émetteurs postent des messages en fonction de mots clés (topics) auxquels s’abonnent plusieurs receveurs.
  • Content-based routing: le routage des messages est déterminé selon le contenu du message ou par une fonction externe.
  • Queued file transfer: on n’envoie plus de simples messages mais des fichiers, voire tout le contenu d’un répertoire.

Ces différentes architectures se combinent bien sûr entre elles, je pense particulièrement aux transactions. Ces schémas de base un peu abstraits rejoignent des concepts ou des applications connus de tous. Un serveur de mail par exemple s’appuiera sur un « store-and-forward », un chat sur un « point-to-point » ou un streaming de fichier sur un « queued file transfer ». Cette sémantique est un vrai plus pour la phase de conception d’un projet même si ensuite rien n’est figé dans la réalisation.

Derrière ces grands concepts se cachent des briques élémentaires très simples :

  • Queue de message (Message Queue): zone de stockage des messages (en mémoire ou sur le disque). Elle aura les propriétés privée/partagée, durable/transitoire, permanente/temporaire.
  • Zone d’échange (Exchange): l’entité qui accepte les messages et les route vers les queues de messages. Les critères de routage peuvent se faire de plusieurs façons (inspection du contenu, du header, clés de routage…). Les zones d’échange peuvent être créées dynamiquement par les applications clientes.
  • Zone virtuelle (Virtual Zone): ce concept est copié de celui des serveurs HTTP d’Apache. Cette zone crée un espace contenant différentes zones d’échange et de queues de message complètement étanches aux autres zones virtuelles. Donc une connexion au serveur ne pourra être associée qu’à une zone virtuelle. C’est très utile lorsqu’on veut mutualiser les ressources.

Pour le routage, la zone d’échange pourra implémenter différents algorithmes :

  • Direct: la clé de routage correspond exactement à l’adresse de la queue.
  • Topic: la clé de routage correspond à un certain pattern (une expression régulière) de l’adresse de la queue.
  • Routage par le header: analyse une table clé/valeur pour décider vers quelle queue aller.
  • Système : appel à un service externe.

De même les queues de message peuvent avoir des typologies assez variées: durables après un redémarrage de serveur, auto-suppression si plus utilisées, dépendant d’un souscripteur, partagées par plusieurs souscripteurs, répondant à un message particulier…

La gestion des transactions et des transactions distribuées est également spécifiée. Un message envoyé à l’intérieur d’une transaction ne sera récupéré par les souscripteurs qu’à partir du moment où l’émetteur acquittera la transaction. Cependant, cette gestion peut varier selon l’implémentation des serveurs car lors d’un rollback, seules les commandes de l’émetteur sont dépilées. Certains états du serveur peuvent donc être modifiés malgré tout (par exemple la déclaration d’une nouvelle queue de message).

Solutions existantes :

RabbitMQ (Mozilla Public License) est sans doute le broker AMQP le plus connu. Il est basé sur le langage Erlang et ses librairies OTP, développé par Ericsson et réputé pour sa haute-disponibilité et sa tolérance aux pannes (règle des « nine nines » : 99.9999999% de disponibilité !). Au-delà de sa maturité, le point fort de ce produit est sa volonté de faciliter son intégration dans les systèmes existants. Par exemple, des distributions dédiées à Amazon EC2, avec intégration à EBS, sont proposées. La gestion du cluster est également très simple, en une commande on peut rattacher un broker à un autre. Toutes les zones d’échange, les queues de message ou les zones virtuelles seront alors partagées et répliquées. Côté client, une API Java est incluse dans la distribution, très simple et proche de l’API JMS. La communication avec un client JMS est possible grâce à une librairie proposée par OpenAMQ.

OpenAMQ propose lui-même un broker. Développé par iMatix, en C++, une API (WireAPI) est proposée. Sans doute plus complexe à appréhender, un effort particulier a néanmoins été apporté aux outils de développement (débogage, constructions de test…) et de monitoring (log, tuning…). Un langage XML (PAL) a été développé pour scripter des scénarios utiles pour les tests par exemple. Ou encore une console de monitoring pour serveur AMQP. Très pointu, OpenAMQ semble s’adresser à des experts confrontés à des projets soumis à de fortes contraintes. Il y a un côté un peu R&D qui permet par ailleurs de jouer un rôle moteur dans la communauté. A noter également que la distribution linux vient avec une implémentation de RestMS.

Par ailleurs OpenAMQ a fait main basse sur un autre broker AMQP : ZeroMQ. Enfin plus précisément un broker qui implémente plusieurs protocoles dont AMQP. On est ici à la limite du sujet tant cette application s’attache moins à son intégration dans une application de gestion classique qu’à construire une bête de course aux performances affichées impressionnantes (13.4 microsecondes de latence end-to-end, 4.1 millions de messages à la seconde).

Avec Qpid on revient un peu sur terre. Ce broker est incubé chez Apache et ne semble a priori rien apporter de plus que ceux cités plus haut. Il vaut malgré tout le coup de s’y intéresser pour les différents frameworks et librairies auxquels il s’intègre et en premier lieu celles d’Apache (Axis2, Camel, Synapse). Il est également intégré à la distribution de Red Hat MRG et est compatible avec l’outil de visualisation et de contrôle HermesJMS.

A noter également que le projet très en vue HornetQ de JBoss prévoit également de supporter ce protocole dans une prochaine version.

Perspectives et enjeux

Une communauté

La capacité d’AMQP à s’imposer comme un standard sera liée à sa capacité à drainer une vraie communauté autour de lui. Cette communauté se divise en deux actuellement : les membres du groupe de travail AMQP et la communauté open source.

Les membres du groupe de standardisation sont eux-mêmes divisés en trois familles : des fournisseurs de brokers AMQP (RabbitMQ, OpenAMQ…), les clients historiques (JPMorgan, Goldman Sachs…) qui poussent ces solutions et les fournisseurs de solutions matérielles (Cisco, Solace Systems Inc., Tervela Inc. …). Ce mélange a le gros avantage de proposer d’ores et déjà des solutions implémentées et en production qui éprouvent ce standard et l’enrichissent en retour. La réalité du terrain guide largement les spécifications comme le montre leurs Business Requirements.

Du côté OpenSource par contre la communauté reste encore discrète. En faisant une recherche rapide sur internet on trouve tout de même une bonne quantité de projets, plus ou moins expérimentaux :

  • RestMS pour poster des messages directement en Rest.
  • amqp-js pour poster des messages en javascript.
  • ici une idée pour faire du twitter avec html5.
  • réplication en base de données.
  • des librairies spring pour utiliser de façon transparente les brokers.

Du chemin reste encore à faire, mais la diversité des projets prouve malgré tout qu’il y a une demande.

Une version de référence

Pour l’instant la version 0.10 est la dernière version officielle. Mais la plupart des brokers sont en version 0.8 ou 0.9. En effet, tout le monde attend la vraie version de référence, la 1.0. qui devrait sortir cette année. Elle devrait apporter de gros changements : un système d’adressage inspiré des mails (queue_message@my_server), le remplacement des zones d’échanges par deux nouvelles entités (une queue d’entrée et un service d’échange), la suppression des Virtual Hosts (conséquence de la suppression des zones d’échanges), l’amélioration de la partie administration du broker et l’ajout de support pour les services DNS.

Ces gros changements apportent sûrement des améliorations majeures à ce protocole. Il n’y a plus qu’à espérer que la migration se fera rapidement. Il est difficile de dire aujourd’hui si les clients sur les versions 0.x pourront se connecter à cette nouvelle version de façon transparente, mais si ce n’est pas le cas, cela risque de casser la dynamique autour d’AMQP.

La concurrence

La lutte est assez féroce dans le domaine du MOM. Si on met de côté Websphere MQ et Tibco, il existe de nombreuses solutions, parfois assez éloignées conceptuellement.

On peut s’en douter, ActiveMQ ne reste pas les bras croisés. Ils poussent entre autre une solution générique, STOMP, très simple d’utilisation mais moins complète et moins performante. Ils annoncent aussi une compatibilité AMQP, sans qu’on sache très bien comment.

Jusqu’à un certain point, ce protocole rentre également en concurrence avec XMPP, le protocole de messagerie instantanée.

MuleMQ est apparu également sur la scène et est proposé comme broker dans la nouvelle distribution de l’ESB Mule. C’est un broker JMS fourni avec quelques outils. Le « tout-intégré » de cette solution peut être assez attirant, par contre on peut regretter que MuleSoft s’éloigne de plus en plus de l’Open Source.

Au contraire, HornetQ joue le jeu de l’Open Source et peut profiter de la grande expérience de JBoss dans ce domaine. Mais cela reste du JMS… Cela sera sûrement la solution privilégiée pour les applications tournant sur JBoss mais difficile de dire si la solution out of the box aura du succès.

Au final JMS est le vrai concurrent d’AMQP même si encore une fois les deux peuvent vivre ensemble. Un adaptateur JMS pour AMQP peut sembler intéressant pour des projets qui migrent vers un nouveau broker, mais il semble plus pertinent pour un nouveau projet de commencer directement dans ce nouveau standard. Par exemple l’utilisation de la librairie Java de RabbitMQ est vraiment très proche de l’API JMS et la vitesse d’apprentissage semble assez rapide pour un développeur Java.

Car un des problèmes de JMS c’est justement son manque d’interopérabilité avec d’autres langages. A cet égard il est intéressant de remarquer que Microsoft s’intéresse de près à AMQP. Depuis 2008 il participe au groupe de travail et a collaboré activement avec QPid pour la version C++ du broker. Etre agnostique vis-à-vis de l’environnement DotNet ou Java serait sûrement une carte majeure de ce standard.

Conclusion

Les solutions propriétaires comme IBM et Tibco ne sont pas réellement menacées par ce nouveau concurrent car leurs solutions sont très complètes, éprouvées et ils fournissent un support sérieux qui rassure les DSI. Le défi d’AMQP est moins de concurrencer ces leaders que de promouvoir l’architecture orientée message au sein de projets de taille moyenne et/ou open-source qui n’ont pas forcément un gros budget à investir. L’adoption massive de ce modèle de conception imposerait AMQP comme le protocole référent tant sa spécification est avancée et complète.

Mots-clefs :, , , ,