Vers Erlang via XMPP

XMPP , né Jabber, m’occupe depuis maintenant quelques mois.
Ce protocole s’occupe de la messagerie instantanée, et se cache derrière le réseau GoogleTalk.
Une de ses grosses forces est l’ouverture et l’interopérabilité entre les serveurs XMPP.
Il faut imaginer le réseau XMPP comme le réseau de routage des emails. L’utilisateur est indentifié via son jid (Jabber ID) : eric@cestari.info . Ca ressemble à une adresse mail, et pour cause. Un ami, Olivier, est sur GoogleTalk. Son jid est of@gmail.com . Lorsque je souhaite envoyer un message, il est routé par mon serveur (cestari.info) vers le serveur gmail.com qui délivre enfin le message à Olivier.

Intégré aussi, le système de chatroom, de publication/abonnement, annuaire, etc.

Bref, le protocole de messagerie instantanée qui finira par gagner🙂.
Je voulais installer un serveur XMPP sur mon serveur, pour jouer avec et écrire une version custom du module MUC (multi-user chat, les chatrooms).
Parmi les serveurs XMPP les plus répandus, j’en ai testé 2 et gardé 1.
OpenFire : Ecrit en Java, administré via http. Respecte les principales XEP (extensions de XMPP). Dimensionné pour 5000 utilisateurs simultanés, avec la possibilité d’utiliser des connecteurs pour augmenter la capacitée.
J’ai eu un problème de connexion S2S (Server to Server) vers d’autres serveurs comme GoogleTalk. J’ai arrêter de creuser dessus, bien que Java soit le langage que je connaisse le mieux.
ejabberd : Ecrit en Erlang (on y arrive !), très bonne couverture du protocole et de ses extensions. Et ensuite, les trucs mortels :

  • Mise en cluster : J’ai besoin de plus de puissance ? j’ajoute un serveur avec une nouvelle instance d’ejabberd que je connecte en 30 secondes, sur la première.

  • Possibilité de mettre à jour le code sans interruption : Je compile, je me connecte à la console du serveur, je lui dit que le code d’un module a été mis à jour, et les requêtes suivantes seront traités par la nouvelle version.

  • Scalabilité incroyable : on peut lui balancer des utilisateurs … Il existe des installations d’ejabberd qui gèrent des centaines de milliers d’utilisateurs et des dizaines de milliers d’utilisateurs simultanéments. Un simple PIII 1,5GHz gère 2000 messages par seconde et 7000 utilisateurs connectés !

Toutes ses fonctionnalités arrivent avec un coût. Tout est écrit en erlang . Langage inventé par les suédois d’Ericsson, pour avoir un outil adapté au développement de leurs produits télécom. Ce petit film indépendant très cheesy présente les avantages d’Erlang. Avant de cliquer sur ce lien, n’oubliez pas qu’il s’agit des concepteurs du langage eux-même qui s’occupent de la présentation.

Je regarde un peu le code source d’ejabberd, et je comprends initialement que dalle. Regardez plutôt.

Interlude Java ….

Pendant la phase de réflexion, je m’oriente vers des bots XMPP qui répondrait aux requêtes. J’utilise la librairie Smack , par Jive Software. (oui ceux derrière OpenFire !). C’est du Java, je connais. En quelques heures et 300 lignes de code j’ai deux bots qui se connectent à mon serveur, qui causent entre eux et gèrent des chatrooms.

Mais ca ne me plaît pas. Même si l’informatique distribué, c’est toujours marrant, le côté mystérieux et “best kept secret” m’intrigue.

En effet, les avantages d’ejabberd sont directement des avantages du langage et de l’environnement Erlang. Il fonctionne sur une machine virtuelle comme Java.

Du coup, je creuse. Je tombe sur des blogs : Tenerife Skunkworks , Joel Armstrong (l’un des concepteurs, justement) et Yariv’s Blog , qui parlent causent erlang.

Des PDF intéressants :
Getting started with Erlang
La thèse de Joel Armstrong

Et comme par hasard, ce dernier vient de publier chez Pragmatic Programmers , Programming Erlang .

J’achète le PDF (des bouts sont dispos sur la page du livre). Pas le temps d’attendre la livraison, et avec un dollar aussi bas … c’est cadeau.

Et finalement, petit à petit, le code source de ejabberd commence à prendre sens.

Après 2 jours de travail, et une dizaine de programmes de test, et une première bidouille sur un module d’ejabberd, je sens que je peux vous parler de manière plus informée de ce langage.

Les caractérisques notable d’Erlang :

  • Langage fonctionnel, comme Lisp et OCaml
  • Donc largement basé sur les closures et fonctions anonymes, ce qui rend la programmation événementielle très pratique à utiliser.
  • La communication se fait uniquement par passage de message d’un processus à l’autre, il n’y a pas d’état global
  • Les processus sont complètement isolés, donc pas de synchronisation à faire. Chaque processus a une boite à message qu’il relève avec receive. Les processus sur des noeuds (instances) séparés peuvent communiquer très simplement.
  • La création d’un processus, et le changement de contexte ne coûtent rien. Un petit script qui va créer 20000 processus créera chacun d’eux en 2,5 ms.
  • Le pattern matching et les variantes de fonctions permettent d’exprimer la gestion des cas particuliers :

 -module(testblog).
 -export([hello/1]).

 hello({hello, eric}) ->
     io:format("Bonjour Eric~n"),
     ok;
 hello({hello, Name}) ->
     io:format("Bonjour, ~w~n", [Name]),
     ok;

 hello({Action, Name}) ->
     io:format("action : ~p pour : ~p~n", [Action, Name]),
     ok.

Le tuple (le truc entre {}) passé en paramètre sera testé sur chacun des prototypes en partant du haut. Les mots commençant par une minuscule sont des atomes (utilisés entre autres comme clés. hello represente un truc qui s’appelle hello et qui peut être identifié par hello.) Les mots commençant par une majuscule sont des variables.

Donc :

  • testblog:hello({hello, eric}) appelera la première version.
  • testblog:hello({hello, marc}) ne sera pas matché par la première version, car marc est différent de eric. On teste sur la deuxième. Le premier élément est l’atome hello, et le deuxième est une variable, que je peux matcher avec n’importe quoi (donc marc). Il n’y a pas d’autres éléments dans le tuple, donc cette version de la fonction convient. C’est donc celle-ci qui est exécuté.
  • testblog:hello({bonjour, eric}). Seule la troisième version de la fonction accepte un premier paramètre différent de 0.

Enfin bref, ce billet n’est pas un tutorial sur Erlang, c’est un truc qui peut vous donner envie de l’utiliser.

Une fois qu’on sait lire la syntaxe du langage (ce qui ne prend que quelques heures), on commence à apprécier la clarté compacte qu’elle engendre.

Du coup, je me suis livré à une étude non-scientifique sur la complexité relative d’un gros projet entre Java et Erlang, en regardant le nombre de lignes entre ejabberd et OpenFire.
Alors que OpenFire compte à peu près 200 000 lignes , ejabberd n’en compte que 80 000 , avec plus de fonctionnalités.

Damn !

Un autre exemple, comparaison des performances entre Apache et yaws (serveur web écrit en erlang). Le benchmark s’attache au nombre de connexions simultanée.
Apache lâche autour de 4000 connexions simultanées. Yaws fonctionne toujours à 80 000 connexions simultanées.

Duh !

Pour démarrer, Process One, le sponsor de ejabberd maintient CEAN (Comprehensive Erlang Archive Network), le CPAN d’Erlang. Avec des packages pour démarrer .

J’en re-parlerais très bientôt. Pour l’heure, il est samedi, et Martin veut jouer avec son papa.

%d bloggers like this: