Getting started with Node.js : Part 1

Vous en avez peut être entendu parler, l’un des outils hype du moment est node.js. On le voit partout sur les timelines Twitter et de façon plus surprenante, souvent relayé par des javaistes. Node.js est la pour vous aider à coder côté serveur des applications scalables et qui tiennent la charge comme jamais : c’est le fameux C10K problem. C’est un sujet vraiment passionnant, et on trouve quantité de ressources dessus.

Fact 1 : node.js est un outil pour créer des serveur javascript.

Du Javascript côté serveur! Pourquoi un tel engouement me direz vous ? Le Javascript, on connaît à peu près, on en fait souvent côté client avec des librairies géniales… Mais de là à en faire aussi sur le serveur ! C’est lent en plus le Javascript non ?
Niveau lenteur, vous pouvez être rassuré : node.js se base sur l’excellent moteur javascript Google V8, l’implémentation utilisée dans Google Chrome. Donc disons que cela va assez vite (et vous trouverez des pseudos benchmarks qui penchent dans l’une ou l’autre direction). On est finalement pas si loin de Java : Lars Bak, un des contributeurs de V8, a travaillé sur la JVM et Hotspot (et l’un de ses brevets était d’ailleurs dans la contestation d’origine de Oracle vs. Google).

Fact 2 : node.js est un outil pour créer des serveurs asynchrones et non bloquants

Javascript admettons, mais quelle avantage par rapport à mon serveur Apache préféré ?
L’approche historique et basique des serveurs web était de forker un process pour une requête entrante. Lorsque vous avez plusieurs milliers de connexions on se retrouve vite à plusieurs milliers de process. Qui demandent chacun du temps pour le fork (fork latency), de la mémoire pendant leur exécution, des changements de contexte, un scheduler qui doit dire qui peut faire quoi (même si depuis linux 2.6, le scheduler est en O(1)), et bien sûr de les nettoyer une fois fermés.
Apache Httpd utilise ce système de ‘one process per connection’ avec évidemment des subtilités (pre-fork des process, chaque process gère plusieurs requêtes), mais, de façon schématique, on retrouve donc ces problèmes pour un nombre important de connexions.

L’une des solutions plus efficaces était d’utiliser des threads à la place des process, ou en complément (pour en revenir à Apache Htppd, c’est la qu’intervient le fameux mod worker). Mais c’est encore lent sur certains OS. D’où l’utilisation de thread pools : les threads sont créés en bloc au démarrage puis chaque thread est affecté à une connexion. Les problèmes commencent quand vous avez plus de connexions que de threads disponibles : la requête est alors en attente. Pas encore le top niveau scalabilité…

A la différence de notre Apache Httpd, Node.js ne se base pas sur des threads : c’est un serveur asynchrone qui utilise un process monothread et des I/O non bloquants. L’asynchronisme permet au thread d’exécuter des callbacks lorsqu’il est notifié d’une connexion. Contrairement au modèle évoqué ci-dessus, node.js ne réserve pas un thread à chaque connexion, ce qui va lui permettre de tenir de bien plus fortes charges sans problème de mémoire.

Les I/O regroupent les accès disques, accès base de données, accès réseaux, bref tout ce qui prend du temps sur un ordinateur moderne (latence, débit limité etc…). Ici tous les I/O sont non bloquants, c’est à dire que tout appel est effectué en asynchrone, avec un callback qui sera exécuté une fois l’accès réalisé. Et tous les modules pour node.js doivent utiliser ce principe. Heureusement, même si node.js est relativement jeune, on trouve déjà près de 2000 modules disponibles (basés sur common.js et simples à developper)!

Cela permet alors de servir plusieurs centaines de requêtes par seconde sans problème.

D’autres serveurs proposent ce principe et certains depuis des années :
nginx (prononcé EngineX) par exemple. Avec des performances intéressantes. Lighttpd lui est souvent comparé (merci à @jponge).
Twisted aussi pour les fans de Python.
EventMachine pour les rubyistes.
– En Java, on se tourne vers JBoss Netty, Apache Mina ou Deft (ou Loft, un portage de deft en Scala, merci à @samklr). NIO2 se profilant à l’horizon, les serveurs Java n’auront peut être plus grand chose à envier à node.js. Même JavaEE, avec la spécification Servlet 3.0 et le support de l’asynchronisme suit ce chemin.

Fact 3 : node.js est multi OS

La plupart de ces serveurs se basent, comme node.js, sur l’instruction Unix select (ou des équivalents améliorés comme epoll voire des non POSIX comme kqueue) pour être notifiés d’une nouvelle connexion avant de se rendormir. Et quid de Windows ? C’était justement la nouvelle de ces derniers jours : Microsoft va supporter la société Joyent, où travaille le créateur de node.js, Ryan Dahl, pour un meilleur support de leurs OS.

Voilà comment faire un premier article sur node.js sans en montrer une seule ligne !
Il est probable que vous n’ayez que rarement à traiter 10000 users en parallèle : mais si c’est le cas node.js est un outil intéressant à connaître. Au delà de node.js en particulier, il devient illusoire de pratiquer le métier de développeur web sans connaître un minimum de Javascript. Node.js m’a donné envie de m’y remettre et c’est déjà ça !

Si vous voulez voir comment faire des websockets facilement avec node.js et continuer la découverte de cet univers foisonnant, stay tuned !

À propos de Cédric Exbrayat

Cédric Exbrayat, développeur et fondateur Ninja Squad, se réunit avec ses semblables régulièrement que ce soit au Lyon JUG ou à Mix-it, dont il est le fondateur. Java et JS for food and fun.

Publié le 28/06/2011, dans Getting started, et tagué , . Bookmarquez ce permalien. 14 Commentaires.

  1. Il y a aussi Lighttpd en serveur basé sur une boucle d’évènements asynchrones.

  2. Bon format (taile,liens pour aller plus lion) et bon article Félicitations.

  3. Ou loft, un port de Deft en Scala.

  4. Non, encore très experimental, mais j’ai lu sur infoQ http://www.infoq.com/articles/deft-loft

  5. J’avais mis le lien dans l’article suite à ton commentaire. Merci

  1. Pingback: Getting started with Node.js : Part 2 « Hype Driven Development

  2. Pingback: Trello, encore un peu de Node.js « Hype Driven Development

  3. Pingback: Getting Started with Hadoop : Part 1 « Hype Driven Development

  4. Pingback: Back from Devoxx : Play! 2, hopes and fears « Hype Driven Development

  5. Pingback: Un an de hype! « Hype Driven Development

  6. Pingback: JUGSummerCamp 2012 « Hype Driven Development

Répondre à Cédric Exbrayat Annuler la réponse.