Inventaire (rapide) de solutions pub/sub temps réel
Pub/Sub en temps réel – WTF ?
Derrière ce nom galvaudé, on peut trouver pleins d’exemples d’applications:
- Application de chat / clavardage
- Statistiques sur les utilisateurs connectés au site
- remontées d’activités / streaming de données
- …
D’autres termes/protocoles peuvent s’apparenter à ce que je cherche à décrire : Bayeux, Comet …
Je vous invite à lire ce Billet qui fait un état de l’art (un peu long): Quand les éléPHPants regardent passer la Comet de Bayeux. de Clochix.
Publisher/Subscriber (pub/sub)
Le protocole Pub/Sub est un *pattern* (modèle) de gestion de messages entre utilisateurs.
Il met en jeu deux acteurs:
- Les publishers (expéditeurs) qui postent des nouveaux messages.
- Les consumers/subscribers (destinataires), qui reçoivent les messages.
Une des particularités de ce protocole réside dans la transparence de l’envoi des messages.
Les messages transitent dans des canaux « nommés ». Les destinataires s’abonnent à des canaux afin de recevoir des messages, et l’émetteur envoie dans un canal.
La communication des messages est en théorie anonyme. L’expéditeur ne connait pas les destinataires, et le destinataire ne connait pas l’expéditeur.
Pour l’expéditeur, c’est un peu comme envoyer un mail dans une mailing liste, on ne connaît pas (forcément) tous les destinataires.
Pour les destinataires, c’est comme recevoir un recommandé. On sait qu’un message nous attend, mais on ne connait pas l’émetteur tant qu’on ne va pas chercher le contenu du recommandé.
On peut assimiler le protocole pub/sub à du broadcasting de messages.
Un peu plus loin – Gestion de files de messages
Derrière le mécanisme pub/sub on retrouve des algorithmes de gestions de queues, de files de messages. Le genre de trucs qui nous rappelle les algorithmes FIFO / LIFO.
En effet, pub/sub assure que chaque destinataire recevra les messages dans l’ordre d’envoi.
Cependant, attention, suivant la solution choisie le système n’assure pas la réception d’un message. Après plusieurs essais d’envoi vers un receveur, le serveur peut abandonner l’envoi.
Temps réel
Notre article se place dans une problématique de temps réel avec un trafic important.
Les subscribers et les publishers sont des navigateurs web. Le serveur HTTP permet de faire la liaison entre le publieur et les différents destinataires.
La notion de temps réel ajoute une complexité dans la mise en œuvre de pub/sub. En effet, les différentes techniques utilisées pour le temps réel (long polling, websocket) demandent à mettre en place une solution qui permet de gérer :
- un grand nombre de connexions simultanées
- des connexions longues,
- un transfert de données rapide
Objectifs et limitations
Après avoir exposé nos besoins et nos problématiques, on pourra se rendre très vite compte qu’il n’est pas opportun de développer et déployer une solution de pub/sub dans un environnement Apache / Php classique.
Vous trouverez un certain nombre d’articles sur la problématique de la charge serveur et du temps réel.
Dans le cadre de solutions php, je vous invite à lire
Realtime communications techniques with php sur slideshare.
Concernant la gestion d’un grand nombre de connexions, C’est le problème C10K:
C10K Problem
La connexion et le transfert de données en temps réel entre les internautes peut se résoudre notamment grâce à des solutions de serveurs COMET, de push.
Comet Serveur sur Wikipédia
Les solutions « clefs en main ».
Ces solutions proposent la gestion de pub/sub à travers un serveur HTTP COMET. Elles gèrent donc le pub/sub et la connexion avec les navigateurs.
Module Pub/Sub pour Nginx
Nginx n’a pas pas la limitation C10K, il permet donc de pouvoir gérer un grand nombre de connexions.
Le module Pub/Sub est une solution simple pour mettre en place un mécanisme pub/sub. Il permet de faire transiter des données au format Texte.
Je vous invite à lire ce retour d’expérience et d’expérimentation. L’auteur fait du broadcasting d’images:
http://rsms.me/2009/10/01/comethttp-push-with-nginx.html
APE – Ajax Push Engine
APE est un serveur COMET qui gère nativement la gestion de pub/sub en temps réel.
APE permet de coder des modules en Javascript du côté client comme du côté serveur. Le serveur instancie le moteur Javascript du navigateur Firefox ( SpiderMonkey), et execute les scripts développés (par nos soins)
La gestion de la connexion client/serveur est complétement transparente. APE utilise la technique de PUSH adaptée en fonction des capacités du navigateur (longpolling, websocket).
Une version 2 est en cours de finalisation sur GitHub.
Quelques lectures:
Node.js
Node.js est un serveur qui interprète lui aussi du Javascript. Il utilise le moteur V8 de Google Chrome.
Il ne permet nativement d’implémenter Pub/Sub et ne permet pas non plus de gérer la connexion avec les clients.
Cependant, il existe:
- le module socket.io qui permet de gérer de façon transparente avec les clients. Cette librairie se déploie du côté client et du coté serveur.Elle permet de mettre en œuvre du longpolling ou des websockets.
- plusieurs modules pour s’interfacer avec des services « purs » de pub/sub, que nous allons exposer dans la suite.
Quelques lectures:
Un servive pub/sub en node.js
Les services de pub/sub
Il s’agit ici d’énumérer des solutions de pub/sub. Attention, ces serveurs ne gèrent pas la connexion et la communication avec les clients. Il faudra mettre en place un serveur HTTP entre les deux.
Il peut être intéressant de découpler la partie pure HTTP du service pub/sub, notamment si l’on souhaite pouvoir accéder au service pub/sub dans d’autres contextes que le temps réel(tâches cron par exemple).
XMPP Pub/Sub
Le protocole Pub/Sub est partie intégrante du protocole Jabber. (les specs se trouvent ici http://xmpp.org/extensions/xep-0060.html).
Les différents serveurs Jabber proposent des services ou extensions pub/sub.
Les serveurs Jabber peuvent s’interfacer avec des serveurs HTTP de façon assez simple. Certains serveurs possèdent des extensions BOSCH (Bidirectional-streams Over Synchronous HTTP ) et permettent à des clients Javascript de se connecter directement sur le serveur XMPP.
Quelques lectures:
OpenFire un serveur Xmpp en java.
Ejabberd un serveur Xmpp en Erlang.
Redis Pub/Sub.
La base de données NoSQL Redis propose des services pub/Sub.
Fonctionnellement c’est assez simple et peut paraitre limité, dans la mesure ou il s’agit ici d’une implémentation stricte de pub/sub (on ne peut pas envisager des communications précises entre consumer et producer).
Redis s’interface avec un grand nombre de langages: PHP, Javascript (module Node.js).
Quelques lectures:
http://blog.redistogo.com/2010/08/18/node-and-redis-pub-sub/
Serveurs AMQP (Advanced Messaging Queue protocole).
Il est assez naturel d’implémenter le protocole AMQP avec les serveurs de queues de messages, puisque la gestion de files de messages répond entre autre à ce type de besoin. La mise en œuvre du protocole pub/sub semble plus ou moins complexe en fonction du serveur choisi. J’ai bien aimé la doc de RabbitMQ à ce sujet : http://www.rabbitmq.com/tutorials/tutorial-three-python.html (python)
Il existe de nombreuses solutions de serveurs AMQP. Vous trouverez tout un tas de comparatifs/benchmarks sur le web à ce sujet.
Le choix pourra se faire en fonction de la techno que vous utilisez pour interfacer pub/sub et de sa facilité d’intégration.
Pour le langage PHP, j’ai bien aimé cet article (pour l’inventaire) pondu par la communauté Drupal : http://groups.drupal.org/node/36428
Conclusion
Gérer du broadcasting de messages en temps réel nous demande donc de gérer deux problématiques :
- La gestion des connexions et du protocole HTTP.
- La gestion du service Pub/Sub.
Les solutions clefs en main paraissent plus simple à mettre en œuvre tant au niveau du serveur qu’au niveau du client. Cependant, elles nous permettront d’accéder au service pub/sub uniquement dans via le protocole HTTP.
Le choix d’une solution découplée nous permet d’accéder au service pub/sub dans d’autres contextes que le temps réel. Il faudra alors choisir un serveur HTTP pour gérer le temps réel. Dans ce cas, par leur architecture et la philosophie du langage, les solutions Javascript (Node.js) répondent parfaitement au besoin de temps réel.
Comme beaucoup de publications à ce sujet, cet inventaire est uniquement descriptif je n’ai pour le moment aucun retour d’expérience…
-
http://www.adrtimes.com/ Articles on ADR

