af83

De la répartition de charge en Ruby on Rails 1/2

Cet article a pour but de décrire l'architecture employée derrière le site de micro-blogging Noumba. Il n'a pas pour objectif d'être exhaustif ni de prétendre proposer la solution idéale, mais seulement présenter un moyen de résoudre certaines contraintes selon notre contexte.

Micro-blogging

Le micro-blogging est un concept, lancé par Twitter, qui permet de s'exprimer en de courtes phrases, tenant en une centaine de caractères de manière à pouvoir être lu depuis un téléphone portable, par SMS ou WAP. En une phrase on ne communique le même type d'information que sur son blog. Cela va donc de son humeur, un lien, ou une rapide information qui ne nécessite pas un long exposé. Ce type d'information sont plus courante que celle que l'on écrirait sur son blog, et à ce titre le micro-blogging est un complément au blog plus qu'une alternative.

Le corollaire est la possibilité de s'exprimer depuis son téléphone portable vers le site.

Au final un site de micro-blogging est souvent utilisé en tant que passerelle entre 2 outils de communication (Phone2Phone, Desktop2API, Phone2Jabber, Web2…).

Contexte

Noumba est un site web de micro-blogging en Ruby on Rails. Il est ouvert à tous, mais son orientation commerciale le prédispose à une certaine tranche d'âge d'utilisateurs, entre 13 et 25 ans. De fait il est pour l'instant plus utilisé pour du chat que du micro-blogging, ce qui génère un fort nombre de messages par utilisateur.

En outre de part le profil des utilisateurs, des filtres sont indispensable afin de garantir une certaine qualité de contenu et de confidentialité.

Pour le reste, les contraintes sont les mêmes que des sites tels que Twitter ou Jaiku, cependant Noumba a ceci de particulier qu'il propose un certain nombre de satellites utilisés par des partenaires, tel que SFR (sfr.noumba.net), NRJ, (mikl.noumba.net, 6-9.noumba.net) MyMajorCompany (mymajorcompany.noumba.net), MCM (mcm.noumba.net), …

Contraintes

Des traitements asynchrones

Lorsqu'un message est posté, des traitements sont appliqués (filtrage, routage, emails, logs,…). Ces traitements ne doivent pas augmenter la latence entre l'utilisateur et le site web. Il n'est donc pas possible de les effectuer de manière synchrone, c'est à dire imposer à l'utilisateur d'attendre leur fin avant de lui rendre la main. Si un fonctionnement synchrone est envisageable avec quelques utilisateurs en simultané, il est tout bonnement impossible pour un site à vocation grand public si l'on veut respecter une certaine qualité de service.

La solution est d'effectuer ces traitements de manière asynchrone, c'est à dire en parallèle, sans imposer à l'utilisateur leur fin pour lui rendre la main.

Les solutions

background

La première solution utilisée sur Noumba fut backgroundrb. Cet outil fournit un serveur de tâche permettant de les paralléliser dans un processus. Si cette solution est intéressante pour quelques tâches simples, elle n'est plus possible dans le contexte lourd d'un micro-blogging, d'autant plus que backgroundrb utilisait les threads. Les threads en Ruby sont peu efficaces (green thread) et une telle architecture consomme trop de ressources et est l'origine de bugs difficilement décelables. Ces threads permettent d'exécuter les traitements, workers, cependant la communication entre eux n'est pas aisée ce qui complique l'enchainement des traitements.

Backgroundrb a depuis été repris et n'utilise plus à priori les threads. Malgré tout, une architecture robuste à base de file d'attente est préférable.

Hey MoM ! ou le monde des messages brokers

Les Message oriented Middleware sont des architectures qui permettent de faire communiquer des applicatifs de manière asynchrone par le biais d'une file d'attente. JMS est le MoM le plus connu et un certain nombre d'implémentations libres existent (ActiveMQ, RabbitMQ)

Parmis ceux-ci, certains implémentent le protocole texte stomp, plus simple et adapté à un site de micro-blogging. StompServer en Ruby en fait parti.

Plus de détails sur les MoM

ActiveMessaging.

Ce plugin Rails permet de communiquer vers un serveur MoM. Il lance un poller qui interroge le serveur MoM afin de lui transmettre ou lui retirer les messages. Ce plugin est MoM agnostique, on peut interroger aussi bien un serveur ActiveMQ, StompServer et même AmazonSQS.

Noumba a utilisé un certain temps un backend StompServer / ActiveMessaging. C'est une architecture intéressante cependant l'évolution et la qualité du code de ActiveMessaging sont à surveiller de prêt.

Noumba en tant que micro-blog génère une forte charge. Or cette charge devient vite un handicap pour le bon fonctionnement du poller. La conclusion qui s'impose est que Noumba se doit d'être le plus léger possible en effectuant le moins d'opération même par le biais d'un plugin.

Que REST il ?

REST est en effet la solution la plus simple, la plus standard (HTTP) et la moins lourde. Dans sa dernière architecture, Noumba communique en REST avec un backend, le Hub, également en Rails. Les messages sous forme de Hash sont sérialisés puis transmis au backend. Cependant il est toujours nécessaire d'implémenter une architecture MoM côté Hub afin d'obtenir un fonctionnement asynchrones.

XMPP bien sûr !

Quel serveur robuste fonctionne de fait sous forme de file d'attente, tout en étant robuste et utilisant un protocole standard, connu et ouvert ? XMPP bien sûr ! Ejabberd est un des serveurs Jabber le plus robuste. Etant en erlang, il peut facilement être réparti sous forme de cluster si le besoin se fait sentir.

Entre REST et XMPP il nous manque le lien Ruby on Rails. ActionMessenger vient le combler. Ce plugin Rails permet de transmettre des messages XMPP en utilisant un compte Jabber. Il fonctionne simplement à la manière d'ActionMailer.

Le Hub implémente ce plugin. Il reçoit les objets sérialisés et les transmet à divers comptes Jabber puis répond aussitôt à Noumba au travers de son API REST.

blog comments powered by Disqus