Et si on regardait nodejs

21/07/2011

Quand j’entend beaucoup de développeurs (expérimentés qui plus est) cracher sur Javascript, je me dis qu’il y a un vrai souci avec l’image de ce langage… Car j’ai beau regarder, tester, Javascript reste pour moi l’un des meilleures langages à ce jour. Lorsque l’on voit Firefox codé en XUL (donc en partie en JS) ou encore les capacités extraodinaires de WebGL (voyez le projet Ro.me), je me demande bien pourquoi on lui fait tellement de tort. Et c’est sans compter sur le pojet “node.js” qui est en phase de faire poids devant les grand maîtres des langages web: PHP, Java et Python.

Cela fait en fait des mois que j’amuse avec node.js. J’ai beaucoup travaillé sur le coté “parallélisation” et intégration système. Je me suis monté un petit serveur HTTP complètement autonome, qui répond entre 5 et 400 fois plus vite que Apache (je vous montrerai ça quand j’aurais un peu plus avancé sur le projet).

Alors node.js c’est quoi ? c’est un système permettant de faire en Javascript, coté serveur, des applications serveurs. Il se base sur le moteur “V8” de Google (intégré dans Chromimum/Chrome) qui a l’avantage d’être très rapide. Mais vous allez me dire “quel avantage ?” car si c’est juste pour coder dans un autre langage, il n’y a aucun intérêt…

Et bien des avantages, on en trouve plein… je vais vous exposer les plus intéressantes, et surtout les plus impressionnantes. On va commencer par les performances, basiques, du simple calcul… Testons simplement une bonne vieille suite de Fibonacci en PHP, en Python et en Node/JS:

Pour le python: def fibo(n): if n == 0 or n == 1: return n return fibo(n-2) + fibo(n-1) print fibo(32)

Pour le PHP: <?php function fibo($n) { if ($n == 0 || $n == 1) return $n; return fibo($n-2) + fibo($n-1); } echo fibo(32); echo "\n"; ?>

et enfin en node/js: function fib(n) { if (n==0 || n==1) return n; return fib(n-2) + fib(n-1); } console.log(fib(32));

Ok, donc on lance les tests:

time php fibo.php 
2178309

real    0m9.195s
user    0m8.051s
sys 0m0.011s

time python fibo.py 
2178309

real    0m2.884s
user    0m1.697s
sys 0m0.030s

time node test1.js 
2178309

real    0m0.214s
user    0m0.200s
sys 0m0.012s

Non vous ne rêvez pas… 200ms contre 9 secondes avec PHP et 2.8 secondes pour Python.

Je ne suis pas là pour critiquer les performances des langages su-cités, mais pour montrer que Node.js est très rapide, contrairement aux préjugés qui disent que Javascript est lent. Rappelez vous que JS n’est qu’un langage, l’implémentation est la cause des preformances, pas le langage lui même.

Bref, passons au second avantage, et pas des moindres, node.js permet de coder des applications asynchrones, tirant parti du système d’exploitation qui fait tourner le projet. Je vais préciser un peu plus.

En fait, tout est asynchrone dans node.js. Lire un fichier, écrire un résultat, envoyer les données au client… tout ! Cela implique que la programmation sera évènementielle, et non pas purement procédurale. Cela entraine deux choses à bien assimiler quand nous codons sous node.js: -le code en parallèle peut devenir compliqué si vous ne maitrisez pas les technique asynchrone -il faut penser à traiter les évènements courants

Par exemple, la lecture d’un fichier se fera de la sorte: ` fs = require(“fs”); //instancie le module filesytem

fs.readFile(‘fichier.txt’, function (err, data) { if (err) throw err; console.log(data); });

console.log(“end…”) `

Contrairement à ce que l’on peut croire, “end…” apparaitra **avant** la lecture effective du fichier… et oui, car le callback est lancé après ouverture du fichier, si il a réussit. Cela peut arriver après un instant de latence, donc le code qui suit l’appel à readFile peut s’exécuter avant le callback.

Et j’en passe… il est possible de lancer une commande unix et d’envoyer en continue le flux de sortie au client: ` var fs = require(‘fs’), sys = require(‘sys’);

//ouverture function messages() { var spawn = require(‘child_process’).spawn; var messages = spawn(“tail”, [‘-f’,‘./messages’]); return messages; }

//fonction de serveur http… on va envoyer un resultat de commande au client function server() { var http = require(‘http’); http.createServer(function (req, res){ //entete http… res.writeHead(200,{‘Content-Type’: ‘text/plain’});

    //pour webkit qui demande un lot de donnee minimum... 1024 fait l'affaire
    var empty="", i=0;
    for (i=0; i<1024;i++){
        empty+=" ";
    }
    res.write(empty); //le lot de donnee vide

    //on regarde la sortie de la commande, et on l'ecrit au client
    //chaque fois que nous avons de nouvelles donnees
    messages.stdout.addListener('data',function(data){
        sys.puts("data "+data)
        res.write(data);
    });
}).listen(8000);

} //instancie la commande de messages… var messages = messages(); server(); `

En se connectant avec un navigateur sur le port 8000 du serveur, on reste en attente de données… chaque fois que vous entrez des données dans le fichier “messages” il apparait dans le navigateur… Et l’intérêt dans tout ça ? Et bien ce système asynchrone peut répondre à des miliers de clients en simultanée.

En effet, node.js est prévu pour répondre à des requêtes en masse. Vous pourrez même travailler en grappe de serveurs, faire du long-polling ou encore travailler sur plusieurs ports…

En gros, node.js est en phase de faire front à pas mal de middleware python ou à Apache/PHP… Je vous conseille de voir un peu la documentation de l’API et de tester un peu les possibilités de ce système.

Et enfin, pour vous donner un peu plus de lumières à l’aptitude de node.js, je vous conseille de l’utiliser pour répondre rapidement à des client réseau “limités”, par exemple pour les Iphone et Android (en 3G) ou encore pour des réponses Ajax/Json en long-polling (comme le fait le projet APE).

En ce qui concerne la gestion de site complet, il faudra encore bosser un peu pour avoir des frameworks… même si je suis plutôt porté sur le micro-framework et/ou l’implémentation directe.

Voilà pour la présentation.

Ça peut vous intéresser aussi


Optimisations Copix PHP et Apache

Les temps de réponse… Dieu sait à quel point cela ...


Docker Apache Mysql PHP

Ce matin un collègue me demande “comment tu ferais ...


Poste de développement PHP sous Fedora

Linux est un système parfait pour développer. Simple d’installation,...


Sortie de Knotter

Et bien on y est. Je me suis lancé un ...

Merci de m'aider à financer mes services

Si vous avez apprécié cet article, je vous serai reconnaissant de m'aider à me payer une petite bière :)

Si vous voulez en savoir plus sur l'utilisation de flattr sur mon blog, lisez cette page: Ayez pitié de moi

Commentaires

Ajouter un commentaire

Ajouter un commentaire

(*) Votre e-mail ne sera ni revendu, ni rendu public, ni utilisé pour vous proposer des mails commerciaux. Il n'est utilisé que pour vous contacter en cas de souci avec le contenu du commentaire, ou pour vous prévenir d'un nouveau commentaire si vous avez coché la case prévue à cet effet.