{"id":1069,"date":"2011-11-28T10:30:00","date_gmt":"2011-11-28T09:30:00","guid":{"rendered":"http:\/\/www.alpesjug.fr\/?p=1069"},"modified":"2011-11-28T10:30:00","modified_gmt":"2011-11-28T09:30:00","slug":"compte-rendu-de-la-soiree-hornetq-et-le-web","status":"publish","type":"post","link":"https:\/\/www.alpesjug.fr\/?p=1069","title":{"rendered":"Compte rendu de la soir\u00e9e HornetQ et le Web"},"content":{"rendered":"<div>Jeff Mesnil connait bien son sujet. ll l\u2019expose avec clart\u00e9 et concision.<\/p>\n<p>La pr\u00e9sentation est en 3 parties:<\/p>\n<ul>\n<li>Rappel des concepts de Messaging et JMS<\/li>\n<li>Pr\u00e9sentation d\u2019HornetQ: Messaging dont JMS mais aussi STOMP\/WebSocket et REST<\/li>\n<li>Demo<\/li>\n<\/ul>\n<p><strong>Pr\u00e9sentation de JMS<\/strong>, l\u2019API Java permettant de faire du Messaging. Du classique: point-\u00e0-point avec les Queue et Publish\/Subscribe avec les Topics. Ca permet de dresser le d\u00e9cor et fixer le vocabulaire.<br \/>\nUn message JMS est structur\u00e9 en:<\/p>\n<ul>\n<li>Header: avec des propri\u00e9t\u00e9s d\u00e9finies par JMS, comme la destination<\/li>\n<li>Properties: des propri\u00e9t\u00e9es d\u00e9finies par votre application<\/li>\n<li>Body: ou payload ou corps du message, qui peut \u00eatre de type stream, object, map, bytes. En pratique seul String, bytes ou Map sont utilis\u00e9s.<\/li>\n<\/ul>\n<p>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 \u201clangue\u201d permet d\u2019envoyer les message o\u00f9 \u201clangue=fr\u201d sur un consommateur fran\u00e7ais et les messages o\u00f9 \u201clangue=en\u201d sur un consommateur standard.<\/p>\n<p>Suivent quelques questions d\u2019ordre pratique:<\/p>\n<ul>\n<li>Si un message n\u2019est pas consomm\u00e9, il bloque la queue ? Non: il existe des propri\u00e9t\u00e9s pour \u00e9viter la congestion. Le message est aiguill\u00e9 vers une voie sp\u00e9ciale o\u00f9 l\u2019administrateur pourra analyser pourquoi personne ne veut de lui (le message pas l\u2019administrateur).<\/li>\n<li>Si l&rsquo;application crashe, le message est perdu ? Ca d\u00e9pend: L\u2019utilisateur peut choisir entre:\n<ul>\n<li>confirmation explicite: le MOM attend un signal explicite de l\u2019application pour consid\u00e9rer que le message est consomm\u00e9.<\/li>\n<li>confirmation implicite: L\u2019application n\u2019a pas besoin d\u2019envoyer de confirmation. Ca laisse une petite fen\u00eatre pour un crash de l\u2019application avant le traitement m\u00e9tier du message<\/li>\n<\/ul>\n<\/li>\n<li>Le message peut faire partie d\u2019une transaction. On peut donc imaginer qu\u2019un message d\u00e9clenche une \u00e9criture en base de donn\u00e9e et l\u2019envoie d\u2019un autre message. Soit toutes ces op\u00e9rations r\u00e9ussissent, soit on fait un roll-back et le message reste \u201cnon consomm\u00e9\u201d.<\/li>\n<li>Il est possible de consommer en mode pull (avec un timeout) ou en mode pull (on d\u00e9fini un listener.<\/li>\n<li>Enfin, JMS est une API Java. Elle ne d\u00e9fini pas ce qui passe sur le r\u00e9seau. Donc pour un serveur HornetQ, il faut des clients HornetQ (un simple jar \u00e0 int\u00e9grer). Pour un serveur ActiveMQ, il faut des clients ActiveMQ. Pour passer de l\u2019un \u00e0 l\u2019autre, on met un bridge qui contient les deux types de clients et qui forward de l\u2019un vers l\u2019autre.<\/li>\n<\/ul>\n<p>JMS n\u2019a pas connu le renouvellement et le buzz des autres techno Java (EJB, JSF &#8230;). JMS 2 est seulement en cours de sp\u00e9cification. Pourquoi tant de temps entre JMS 1 et 2 ? Peut \u00eatre tout b\u00eatement parce qu\u2019il n\u2019y a pas un \u00e9norme besoin d\u2019\u00e9volution. On demande simplicit\u00e9 et performance avant tout. D\u2019ailleurs \u00e0 priori JMS 2 n\u2019apporte pas de r\u00e9volutions, il est juste mieux adapt\u00e9s \u00e0 JavaEE 6 (simplifications, injections &#8230;) Voir la r\u00e9cente pr\u00e9sentation de Nigel Deakin, spec lead de JMS 2.0: <a href=\"http:\/\/java.net\/projects\/jms-spec\/downloads\/download\/JMS2.0Devoxx2011.pdf\">http:\/\/java.net\/projects\/jms-spec\/downloads\/download\/JMS2.0Devoxx2011.pdf<\/a><\/p>\n<p>En pratique JMS r\u00e9pond \u00e0 des besoins de messaging o\u00f9 les volumes et les contraintes en temps de traitement et fiabilit\u00e9 sont pr\u00e9pond\u00e9rantes et souvent associ\u00e9 \u00e0 des moteurs de r\u00e8gles et autres Complex Event Processing (CEP) syst\u00e8mes. (Tibco, IBM MQSerie &#8230;)<\/p>\n<p><strong>L\u2019implementation HornetQ<\/strong> en quelques mots:<\/p>\n<ul>\n<li>un serveur simple et ergonomique\n<ul>\n<li>configuration simple<\/li>\n<li>d\u00e9ploiement sans prise de t\u00eate<\/li>\n<li>d\u00e9pendances r\u00e9duites \u00e0 Netty pour les IO<\/li>\n<\/ul>\n<\/li>\n<li>une implementation de JMS performante et fiable !<\/li>\n<li>un Message Oriented Middleware (MOM) multi-protocolaire: JMS, STOMP, REST &#8230;<\/li>\n<li>un modele de messaging souple, non limit\u00e9 aux Queues et Topics de JMS<\/li>\n<li>Une documentation exhaustive: une feature \/ un exemple<\/li>\n<\/ul>\n<p>Le coeur d\u2019HornetQ est un ensemble de classes et d&rsquo;interfaces Java simples et ind\u00e9pendantes de JMS. Agnostique donc.<\/p>\n<p>Quelques anecdotes sur l\u2019impl\u00e9mentation:<\/p>\n<ul>\n<li>Pour la fiabilit\u00e9, il faut \u00e9crire le message sur le disque dur (et pas juste dans un cache). Les RDBMS, bien que pratique, sont abandonn\u00e9s au profit de simple fichiers journaux plus rapide et plus fiable. Le flush est mieux control\u00e9.<\/li>\n<li>Le fichier journal est g\u00e9r\u00e9 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.<\/li>\n<li>Netty (JBoss) est utilis\u00e9 pour ses excellentes performance r\u00e9seau.<\/li>\n<li>Il existe des benchmarks, mais le sujet est toujours d\u00e9licat. On remarque que HornetQ n\u2019a pas peur de s\u2019aligner, contrairement \u00e0 d\u2019autres qui refusent tout simplement les comparaisons.<\/li>\n<li>HornetQ utilise des thread et donc ne fonctionne pas sur Google App Engine. Reste CloudBees, Amazon &#8230;<\/li>\n<\/ul>\n<p>D\u2019un point de vue Messaging, HonetQ propose un model simple inspir\u00e9 d\u2019AMQP:<\/p>\n<ul>\n<li>un producteur envoie les messages \u00e0 une adresse<\/li>\n<li>un consommateur lit les messages \u00e0 partir d&rsquo;une queue<\/li>\n<\/ul>\n<p>A partir de l\u00e0, on peut repr\u00e9senter plusieurs mod\u00e8les de messaging, dont JMS.<\/p>\n<p>Par exemple le binding pour JMS est le suivant:<\/p>\n<ul>\n<li>pour faire une Queue:\n<ul>\n<li>Adresse -&gt; unique queue<\/li>\n<li>Queue -&gt; multiple consommateurs<\/li>\n<\/ul>\n<\/li>\n<li>pour faire un Topic\n<ul>\n<li>Adresse -&gt; multiple queues<\/li>\n<li>Queue-&gt; unique consommateur<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>D\u2019autres mod\u00e8les sont r\u00e9alisable en changeant le binding. Ce m\u00eame principe agnostique lui permet d\u2019offrir plusieurs protocols (en plus de JMS):<\/p>\n<ul>\n<li>STOMP protocole de messaging oriente texte et tcp =&gt; clients dans tous les langages<\/li>\n<li>REST \/ HTTP<\/li>\n<li>&#8230;la voie est ouverte, on pense \u00e0 XMPP, mais pas de demandes de la communaut\u00e9 pour l\u2019instant.<\/li>\n<\/ul>\n<p>Cela rend HornetQ vraiment inter-op\u00e9rable.<\/p>\n<p>Bref HornetQ apporte des solutions de Messaging \u00e0 des contextes vari\u00e9s, au del\u00e0 d\u2019une API java.<\/p>\n<p><strong>La Demo<\/strong> s\u2019inspire d\u2019un cas d\u2019utilisation r\u00e9el:<br \/>\ncommunication entre une flotte de camions et un centre de navigation. Les camions envoient des donnes gps et l&rsquo;application affiche leur position sur une carte (Google Maps)<br \/>\nDeux types de consommateurs l&rsquo;un qui affiche les positions sur une carte et une application java qui stocke et calcule les itin\u00e9raires.<br \/>\nPremi\u00e8re partie: une application Web pour mobile envoie les coordonn\u00e9es du GPS en REST\/HTTP au serveur.<br \/>\nDeuxi\u00e8me 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\u00e9grader d\u2019HTTP \u00e0 TCP et donc d\u2019utiliser STOMP directement sur la socket TCP. La technologie est un peu jeune, mais les possibilit\u00e9s offertes lui assurent un avenir radieux.<\/p>\n<p>Regard inquiet de Jeff face \u00e0 une demo principalement bas\u00e9e sur Javascript et JQuery, mais on n\u2019est pas sectaire au JUG, bien au contraire.<\/p>\n<p>La d\u00e9mo s\u2019est tr\u00e8s bien pass\u00e9, les gens ont pu participer avec leurs SmartPhones. Le mapping du modele de messaging sur du REST pose d\u2019int\u00e9ressant problemes. Actuellement il se base sur le modele \u201cHypermedia as the Engine of Application State\u201d (HATEOAS). L\u2019utilisation des WebSocket pour faire du STOMP en revanche sonne comme une \u00e9vidence.<\/p>\n<p>Jeff a surtout \u00e0 coeur l\u2019interoperabilit\u00e9 avec d\u2019autres languages Python, PHP et l\u2019ouverture vers le Web o\u00f9 le besoin de Messaging est flagrant.<\/p>\n<p>Grand merci<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Jeff Mesnil connait bien son sujet. ll l\u2019expose avec clart\u00e9 et concision. La pr\u00e9sentation est en 3 parties: Rappel des concepts de Messaging et JMS Pr\u00e9sentation d\u2019HornetQ: Messaging dont JMS mais aussi STOMP\/WebSocket et&#46;&#46;&#46;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[15],"tags":[],"class_list":["post-1069","post","type-post","status-publish","format-standard","hentry","category-compte-rendu"],"_links":{"self":[{"href":"https:\/\/www.alpesjug.fr\/index.php?rest_route=\/wp\/v2\/posts\/1069","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.alpesjug.fr\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.alpesjug.fr\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.alpesjug.fr\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.alpesjug.fr\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1069"}],"version-history":[{"count":3,"href":"https:\/\/www.alpesjug.fr\/index.php?rest_route=\/wp\/v2\/posts\/1069\/revisions"}],"predecessor-version":[{"id":1072,"href":"https:\/\/www.alpesjug.fr\/index.php?rest_route=\/wp\/v2\/posts\/1069\/revisions\/1072"}],"wp:attachment":[{"href":"https:\/\/www.alpesjug.fr\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1069"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.alpesjug.fr\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1069"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.alpesjug.fr\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1069"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}