Comment mettre � l'�chelle les applications Node.js ? par Mensur Durakovic
Pour comprendre la mise � l'�chelle des applications Node.js, nous devons d'abord comprendre quel probl�me la mise � l'�chelle r�sout.
Vous savez que Node.js est monot�che, il a son propre thread principal. Ainsi, au lieu de servir chaque requ�te entrante au serveur sur un thread s�par�, il sert chaque requ�te � travers le thread principal. Je vais expliquer cela plus en d�tail car cela peut �tre un peu d�routant.
Ainsi, si la requ�te bloque le thread principal, cela peut affecter les autres requ�tes entrantes. Supposons que vous ayez une simple route /user-profile et qu'il faille 1 seconde pour compl�ter la requ�te. Si 3 requ�tes /user-profile sont faites en m�me temps, voici ce qui se passera :
- l'une des requ�tes sera trait�e en 1 seconde,
- une autre en 2 secondes (parce qu'elle doit attendre 1 seconde)
- et la troisi�me en 3 secondes (en attendant 2 secondes que les 2 requ�tes pr�c�dentes se terminent).
Cependant, Node.js peut d�charger de nombreuses t�ches sur le noyau du syst�me d'exploitation. Le noyau du syst�me d'exploitation est multi-thread. Voici quelques exemples de ces t�ches :
- 1fs.readFile()
- dns.lookup()
- zlib.gzip()
- crypto.pbkdf2()
Les deux premi�res t�ches sont tr�s gourmandes en entr�es/sorties, et les deux derni�res sont gourmandes en ressources processeur.
Ainsi, lorsque le syst�me d'exploitation ex�cute des t�ches, le thread principal de Node.js peut basculer vers d'autres requ�tes. Le syst�me d'exploitation permet � Node.js d'�tre raisonnablement rapide gr�ce � son mod�le de thread principal unique.
Le probl�me survient lorsque Node.js a trop de t�ches qui ne peuvent pas �tre d�l�gu�es au noyau du syst�me d'exploitation. Ces t�ches bloquent alors le thread principal de Node.js, car les demandes commencent � s'accumuler dans la file d'attente.
Il peut en r�sulter un sc�nario peu glorieux comme celui-ci :
- une requ�te arrivant peut devoir attendre qu'un serveur Node.js occup� prenne en charge et traite la requ�te
- plus le serveur est bloqu�, plus le temps d'attente est long
- plus le nombre de demandes est �lev�, plus le temps d'attente est long
�tant donn� que Node.js traite toutes les demandes par l'interm�diaire d'un seul thread principal, il n'est pas possible de traiter des demandes suppl�mentaires en ajoutant simplement des unit�s centrales. Un seul thread ne peut pas fonctionner sur plus d'un c�ur de CPU � la fois.
Voici � quoi ressemble ce sc�nario :
Les demandes sont en attente et le processus Node.js, tr�s occup�, essaie d'accomplir autant de t�ches qu'il le peut. Nous avons l� un processeur qui est en feu alors que les autres sont au repos.
C'est le probl�me de la mise � l'�chelle. Lorsque l'ajout de mat�riel ne r�sout pas les probl�mes de performance.
Solution 1 - Worker threads
Nous pouvons exploiter les Worker threads pour ex�cuter du code JavaScript plus intensif en termes de CPU et lib�rer le thread principal de Node.js.
Voici � quoi cela ressemble :
Chaque demande est toujours trait�e par le thread principal de Node.js, mais le code JavaScript intensif est ex�cut� dans des Worker threads. Ces Worker threads rendent compte de l'ex�cution � leur patron, le thread principal de Node.js.
La partie d�licate des Worker threads et de leur utilisation efficace est d'identifier et d'isoler les parties intensives du code. Cela peut s'av�rer difficile en fonction de la complexit� de la logique m�tier de votre application. Le module Node.js worker_threads doit ex�cuter ces parties intensives du code.
Voici � quoi cela ressemble avec des Worker threads :
Lorsque le code JavaScript intensif s'ex�cute sur des workers, le processus Node.js peut utiliser des c�urs de processeur suppl�mentaires. De plus, le thread principal est lib�r� pour r�pondre � davantage de demandes.
Cette m�thode est connue sous le nom de mise � l'�chelle verticale. La mise � l'�chelle verticale consiste � ajouter des ressources suppl�mentaires au serveur.
Solution 2 - plusieurs instances Node.js
Nous pouvons ex�cuter plusieurs instances de notre processus de serveur Node.js pour r�pondre aux demandes. L'�quilibreur de charge peut r�partir ces demandes entrantes entre les processus Node.js :
Cette approche peut s'av�rer plus pratique car elle ne n�cessite pas d'�tapes telles que l'identification du code JavaScript � forte intensit� de CPU, la communication des threads, etc. Avec cette approche, nous utilisons tous les c�urs de processeurs disponibles.
Une autre variante de cette approche consiste � utiliser diff�rentes machines/ordinateurs pour ex�cuter les processus Node.js :
Dans cette variante, l'�quilibreur de charge r�partit les demandes entrantes entre les processus Node.js ex�cut�s sur diff�rentes machines. Si la charge augmente, d'autres machines peuvent �tre ajout�es pour accro�tre la capacit�.
Cette m�thode est connue sous le nom de mise � l'�chelle horizontale. La mise � l'�chelle horizontale consiste � augmenter la capacit� en ajoutant des n�uds/serveurs � la configuration.
Cette configuration de mise � l'�chelle horizontale peut �tre construite de mani�re rentable dans le cloud (Amazon Web Services, Google Cloud Platform, Microsoft Azure, etc.)
Dans le cloud, un serveur est une machine virtuelle qui peut �tre rapidement ajout�e ou supprim�e � l'aide d'une simple commande. Nous pouvons mettre en place une configuration rentable en d�ployant une machine virtuelle de faible capacit� qui peut �tre ajout�e/supprim�e en fonction de la charge des demandes.
Une chose importante � retenir lors de la mise � l'�chelle des applications Node.js de cette mani�re est de respecter une r�gle : Le processus Node.js qui sert une requ�te ne doit rien stocker dans sa m�moire qui soit sp�cifique � une session.
Si cette r�gle n'est pas respect�e, les requ�tes cons�cutives de cette session seront trait�es par la m�me instance de serveur Node.js. Ainsi, m�me si cette instance est tr�s occup�e et que d'autres sont libres, elle doit toujours servir cette requ�te sp�cifique.
Pour �viter cela, les processus Node doivent stocker les donn�es sp�cifiques � la session dans le magasin accessible � tous les autres processus Node de la configuration :
De cette mani�re, toute instance de serveur Node peut r�pondre � des demandes cons�cutives provenant de n'importe quelle session en recherchant ces donn�es de session dans le magasin commun. Une base de donn�es comme Postgres ou MySQL ou un magasin en m�moire comme Memcached ou Redis peuvent stocker des donn�es sp�cifiques � une session.
Gestion d'une configuration mise � l'�chelle
Lorsque vous avez une application Node.js mise � l'�chelle, vous avez besoin d'outils de gestion pour cette configuration. D'apr�s mon exp�rience, ces 3 outils sont les plus populaires et les plus �prouv�s :
- Nginx avec systemd
- pm2
- Docker
Il n'y a pas de solution miracle. Chacun de ces outils peut �tre utilis� en fonction de votre configuration.
Nginx avec systemd est id�al lorsque l'automatisation DevOps et une configuration horizontalement extensible ne sont pas n�cessaires. Nginx peut jouer le r�le d'�quilibreur de charge et distribuer les requ�tes entrantes. Systemd peut g�rer les processus Node.js (par exemple, red�marrer en cas de crash) et s'occuper des logs avec Syslog.
Le pm2 est id�al lorsque vous recherchez une solution bas�e sur Node et que vous n'avez pas besoin d'automatisation DevOps et d'une configuration horizontalement �volutive. Il peut faire de l'�quilibrage de charge avec son module cluster. Il peut �galement d�marrer, arr�ter et red�marrer les processus Node tout en g�rant les journaux.
Docker est le mieux adapt� lorsque vous avez besoin d'une automatisation DevOps et d'une configuration horizontalement �volutive. Il fonctionne �galement tr�s bien en combinaison avec des services cloud. Docker peut �tre utilis� pour g�rer les processus Node.js s'ex�cutant dans les conteneurs Docker. Les services cloud peuvent permettre d'ajouter/supprimer des machines virtuelles � l'aide d'une simple commande. L'automatisation DevOps peut d�marrer/arr�ter automatiquement les machines virtuelles en fonction de la charge des demandes.
Chaque machine virtuelle ex�cute un conteneur Docker dans des instances Node.js en direct. Dans ce cas, l'�quilibreur de charge peut �tre un service de gestion bas� sur le cloud, comme AWS Application Load Balancer.
La gestion des t�ches et des journaux de Node se fait via les services de conteneurs Docker. L'automatisation DevOps cr�e des machines virtuelles � partir d'images Docker et met � jour l'�quilibreur de charge avec les changements.
Verdict
Il n'existe pas de formule magique ou de meilleure recette pour g�rer la mise � l'�chelle des applications Node.js.
Si vous �tes � court d'id�es, vous pouvez utiliser certains des outils d�crits ci-dessus. Ces outils ont pass� le test du temps, mais n'h�sitez pas � g�rer votre installation selon vos propres r�gles.
Si vous avez une petite application Node.js, vous n'avez pas besoin de compliquer les choses, vous n'avez pas besoin d'avoir une automatisation compl�te et des tonnes de conteneurs Docker. En revanche, si vous avez une application complexe avec beaucoup de services, envisagez les machines virtuelles et les conteneurs en combinaison avec d'autres options.
Source : How to scale Node.js applications ? (Mensur Durakovic)
Et vous ?
Quel est votre avis sur le sujet ?
Voir aussi :
Node.js 20.6 est disponible avec une prise en charge des fichiers de configuration .env et l'int�gration du garbage collector C++ "Oilpan"
The Art of Node - Une introduction � Node.js
Partager