Compte rendu de la soirée HornetQ et le Web

Jeff Mesnil connait bien son sujet. ll l’expose avec clarté et concision.

La présentation est en 3 parties:

  • Rappel des concepts de Messaging et JMS
  • Présentation d’HornetQ: Messaging dont JMS mais aussi STOMP/WebSocket et REST
  • Demo

Présentation de JMS, l’API Java permettant de faire du Messaging. Du classique: point-à-point avec les Queue et Publish/Subscribe avec les Topics. Ca permet de dresser le décor et fixer le vocabulaire.
Un message JMS est structuré en:

  • Header: avec des propriétés définies par JMS, comme la destination
  • Properties: des propriétées définies par votre application
  • Body: ou payload ou corps du message, qui peut être de type stream, object, map, bytes. En pratique seul String, bytes ou Map sont utilisés.

Les champs des Headers et Properties sont accessibles au MOM qui peut faire des filtres ou autres traitements en fonction de leur valeurs. Par exemple, un champ “langue” permet d’envoyer les message où “langue=fr” sur un consommateur français et les messages où “langue=en” sur un consommateur standard.

Suivent quelques questions d’ordre pratique:

  • Si un message n’est pas consommé, il bloque la queue ? Non: il existe des propriétés pour éviter la congestion. Le message est aiguillé vers une voie spéciale où l’administrateur pourra analyser pourquoi personne ne veut de lui (le message pas l’administrateur).
  • Si l’application crashe, le message est perdu ? Ca dépend: L’utilisateur peut choisir entre:
    • confirmation explicite: le MOM attend un signal explicite de l’application pour considérer que le message est consommé.
    • confirmation implicite: L’application n’a pas besoin d’envoyer de confirmation. Ca laisse une petite fenêtre pour un crash de l’application avant le traitement métier du message
  • Le message peut faire partie d’une transaction. On peut donc imaginer qu’un message déclenche une écriture en base de donnée et l’envoie d’un autre message. Soit toutes ces opérations réussissent, soit on fait un roll-back et le message reste “non consommé”.
  • Il est possible de consommer en mode pull (avec un timeout) ou en mode pull (on défini un listener.
  • Enfin, JMS est une API Java. Elle ne défini pas ce qui passe sur le réseau. Donc pour un serveur HornetQ, il faut des clients HornetQ (un simple jar à intégrer). Pour un serveur ActiveMQ, il faut des clients ActiveMQ. Pour passer de l’un à l’autre, on met un bridge qui contient les deux types de clients et qui forward de l’un vers l’autre.

JMS n’a pas connu le renouvellement et le buzz des autres techno Java (EJB, JSF …). JMS 2 est seulement en cours de spécification. Pourquoi tant de temps entre JMS 1 et 2 ? Peut être tout bêtement parce qu’il n’y a pas un énorme besoin d’évolution. On demande simplicité et performance avant tout. D’ailleurs à priori JMS 2 n’apporte pas de révolutions, il est juste mieux adaptés à JavaEE 6 (simplifications, injections …) Voir la récente présentation de Nigel Deakin, spec lead de JMS 2.0: http://java.net/projects/jms-spec/downloads/download/JMS2.0Devoxx2011.pdf

En pratique JMS répond à des besoins de messaging où les volumes et les contraintes en temps de traitement et fiabilité sont prépondérantes et souvent associé à des moteurs de règles et autres Complex Event Processing (CEP) systèmes. (Tibco, IBM MQSerie …)

L’implementation HornetQ en quelques mots:

  • un serveur simple et ergonomique
    • configuration simple
    • déploiement sans prise de tête
    • dépendances réduites à Netty pour les IO
  • une implementation de JMS performante et fiable !
  • un Message Oriented Middleware (MOM) multi-protocolaire: JMS, STOMP, REST …
  • un modele de messaging souple, non limité aux Queues et Topics de JMS
  • Une documentation exhaustive: une feature / un exemple

Le coeur d’HornetQ est un ensemble de classes et d’interfaces Java simples et indépendantes de JMS. Agnostique donc.

Quelques anecdotes sur l’implémentation:

  • Pour la fiabilité, il faut écrire le message sur le disque dur (et pas juste dans un cache). Les RDBMS, bien que pratique, sont abandonnés au profit de simple fichiers journaux plus rapide et plus fiable. Le flush est mieux controlé.
  • Le fichier journal est géré avec Java NIO qui offre de bonne performance. Sous Linux, HornetQ utilise directement linux asynchrone IO via JNI. Cela permet de gagner encore un peu de performance.
  • Netty (JBoss) est utilisé pour ses excellentes performance réseau.
  • Il existe des benchmarks, mais le sujet est toujours délicat. On remarque que HornetQ n’a pas peur de s’aligner, contrairement à d’autres qui refusent tout simplement les comparaisons.
  • HornetQ utilise des thread et donc ne fonctionne pas sur Google App Engine. Reste CloudBees, Amazon …

D’un point de vue Messaging, HonetQ propose un model simple inspiré d’AMQP:

  • un producteur envoie les messages à une adresse
  • un consommateur lit les messages à partir d’une queue

A partir de là, on peut représenter plusieurs modèles de messaging, dont JMS.

Par exemple le binding pour JMS est le suivant:

  • pour faire une Queue:
    • Adresse -> unique queue
    • Queue -> multiple consommateurs
  • pour faire un Topic
    • Adresse -> multiple queues
    • Queue-> unique consommateur

D’autres modèles sont réalisable en changeant le binding. Ce même principe agnostique lui permet d’offrir plusieurs protocols (en plus de JMS):

  • STOMP protocole de messaging oriente texte et tcp => clients dans tous les langages
  • REST / HTTP
  • …la voie est ouverte, on pense à XMPP, mais pas de demandes de la communauté pour l’instant.

Cela rend HornetQ vraiment inter-opérable.

Bref HornetQ apporte des solutions de Messaging à des contextes variés, au delà d’une API java.

La Demo s’inspire d’un cas d’utilisation réel:
communication entre une flotte de camions et un centre de navigation. Les camions envoient des donnes gps et l’application affiche leur position sur une carte (Google Maps)
Deux types de consommateurs l’un qui affiche les positions sur une carte et une application java qui stocke et calcule les itinéraires.
Première partie: une application Web pour mobile envoie les coordonnées du GPS en REST/HTTP au serveur.
Deuxième partie: une application Web affiche les messages utilisateurs et positions en recevant les messages du serveur via STOMP/WebSocket. Rappelons que WebSocket permet de dégrader d’HTTP à TCP et donc d’utiliser STOMP directement sur la socket TCP. La technologie est un peu jeune, mais les possibilités offertes lui assurent un avenir radieux.

Regard inquiet de Jeff face à une demo principalement basée sur Javascript et JQuery, mais on n’est pas sectaire au JUG, bien au contraire.

La démo s’est très bien passé, les gens ont pu participer avec leurs SmartPhones. Le mapping du modele de messaging sur du REST pose d’intéressant problemes. Actuellement il se base sur le modele “Hypermedia as the Engine of Application State” (HATEOAS). L’utilisation des WebSocket pour faire du STOMP en revanche sonne comme une évidence.

Jeff a surtout à coeur l’interoperabilité avec d’autres languages Python, PHP et l’ouverture vers le Web où le besoin de Messaging est flagrant.

Grand merci

Vous aimerez aussi...

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.