Nodejs et la simplification de l'asynchrone

Catégorie: Web (Mis à jour le 15-11-2015 10:56:00)

On entend souvent parler de Nodejs comme une révolution dans le monde du temps réel.

Ce framework réussi l'exploit de démystifier suffisamment la programmation asynchrone pour permettre la création facile de serveurs web.

Fonctionnement d'un serveur web

Pour comprendre comment marche Nodejs, il faut d'abord savoir comment fonctionne un serveur web classique.

En général un serveur web utilise plusieurs processus pour répondre aux requêtes. Dès qu'une connexion arrive, elle est assignée à un processus qui va la traiter. Avec cette architecture, le calcul est simple : 10 requêtes simultanées = 10 processus concurrents.

Comme dans le monde du web les applications serveur passent le plus gros de leur temps à attendre après des opérations d'entrée/sortie, ces 10 processus n'utilisent pas de CPU, mais leur existence consomme de la mémoire.

Nodejs adopte une approche totalement différente. En fait, ce serveur est uniquement monothreadé. C'est-à-dire qu'il n'y a qu'un seul processus qui tourne, malgré les 10, 100 ou 1000 requêtes en cours.

Comment ça marche alors?

Malgré qu'il n'y ait qu'un seul processus, nodejs permet de traiter plusieurs requêtes concurrentes en même temps.

Pour réussir cet objectif, cet outil tire parti du fait que les entrées/sorties prennent du temps et met ce temps à profit pour traiter d'autres requêtes. Ainsi on a l'impression que les requêtes sont exécutées en parallèle alors qu'en réalité elles sont entrelacées.

En nodejs, tout les appels externes sont asynchrones mais notre code reste synchrone.

Graphique illustrant le cas ou deux requêtes asynchrones entrelacent leur execution

On voit sur cette illustration que les deux requêtes sont entrelacées. Chacune profite du temps laissé par l'autre pour s'exécuter.

Les problèmes de cette approche

Dans le cas où notre application passe du temps à attendre via des appels asynchrone (on parle d'io bound), cette architecture fonctionne parfaitement.

Maintenant si notre application à des calculs longs à faire (CPU bound), il faut garder à l'esprit que node ne peux faire qu'une chose à la fois. Les autres opérations asynchrones ne pourront pas débuter tant que cette opération bloquante ne sera pas terminée.

Le graphique suivant montre le cas où deux requêtes arrivent, mais que la première fait des calculs bloquants (synchrones) pendant 10 secondes. Comme le système d'évènements de node est bloqué, la seconde requête doit attendre avant d'avoir une chance de s'exécuter.

Graphique illustrant le cas ou une requete longue bloque une requete courte

Sur cette illustration, on voit bien que la première requête bloque le processus de node et retarde l'exécution de la seconde.

En conclusion

Nodejs est parfait pour une application qui doit gérer beaucoup de connexions simultanées. Par exemple c'est l'idéal pour un service de push (avec socketio!) car ce genre de service est inactif 99 % du temps.

Par contre, si votre application doit faire des calculs lourds, il faudra repasser sur une architecture plus classique ou alors adopter des dispositions particulières (détacher vers d'autres processus).

A lire aussi:

Mon avis sur RG Supervision

[Web] La surveillance et le monitoring représente une part importante pour toute entreprise présente sur internet. Quoi de pire pour un prospect que de tomber sur le site de votre entreprise et de tomber sur un service lent ou indisponible ? Voici une solution...
Suite...

Les nouveautés de PHP 7

[Web] Avec la sortie de PHP 7, j'en profite pour faire un petit tour d'horizon sur ce qu'apporte cette nouvelle version et sur les points à considérer pour la mise à jour.
Suite...