PM2: aborder judicieusement la question de la gestion des processus

Il y a quelques heures à peine, j'ai entamé un débat sur le fait que Node.JS est trop lent pour les grands projets et qu'il devrait préférer Golang, Rust, PHP, etc. L'argument principal de la partie opposée dans ce différend était le fait que JavaScript est monothread. Apparemment, lors du développement d'une application, la productivité repose simplement sur cette unité d'exécution unique et rien ne peut plus être fait - il suffit de la réécrire dans une autre langue. Cependant, les choses sont un peu mieux avec NodeJS qu'il n'y paraît à première vue. Avant de nous plonger dans ce sujet, je tiens à déclarer que je respecte le droit de chaque développeur d'utiliser le langage de programmation qu'il a aimé et qu'il considère préférable dans une tâche particulière.

Après avoir fait une recherche par un mot clé "PM2" sur Habr je n'ai trouvé aucun article consacré à ce gestionnaire de processus. Seules des références uniques dans les articles d'autres utilisateurs. J'ai été excité (fortement dit) avec l'idée de rattraper et de faire la lumière sur ce coin sombre du développement backend sur Node.JS (que beaucoup de gens connaissent, oui, je le sais). Je demande à tout le monde intéressé par cat.



Quelques mots sur PM2 lui-mĂŞme



PM2 est un gestionnaire de processus open source sous licence AGPL-3.0. Au moment d'écrire ces lignes, il a environ 350 000 téléchargements hebdomadaires, selon NPM. Il est principalement utilisé dans les environnements où vous devez exécuter une application sur NodeJS et l'oublier (vous pouvez également l'utiliser avec d'autres langages, mais plus à ce sujet plus tard), ce qui vous permet de regrouper l'application et de répartir de manière flexible la charge entre les cœurs du processeur. Un petit extrait du référentiel PM2 sur GitHub :

PM2 est un gestionnaire de processus de production pour les applications Node.js avec un équilibreur de charge intégré. Il vous permet de maintenir les applications en vie pour toujours, de les recharger sans interruption et de faciliter les tâches d'administration système courantes.


Lors du développement, de nombreux nouveaux arrivants rencontrent un problème lorsque, après avoir "déployé" l'application sur le serveur de production, ils ne savent pas comment la lancer "pour toujours". Ils écrivent set NODE_ENV=production && node app.js dans la console SSH, tout va bien, l'application fonctionne. Fermez la console et l'application ne fonctionne plus. Question StackOverflow - Comment exécuter l'application node.js en permanence? a marqué plus de 237 mille vues pour tous les temps.

PM2 résout ce problème avec une seule commande:

 pm2 start app.js 


Cette commande «diabolise» (de l'anglais «daemonize») le processus NodeJS, surveille sa consommation de mémoire et prend en compte la charge du processeur.

Retour à nos béliers



À mesure que la charge sur le backend augmente, il devient nécessaire de la mettre à l'échelle - à la fois verticale et horizontale - à qui elle est plus pratique dans les circonstances. Comme nous le savons, un processus peut utiliser plusieurs cœurs de processeur, mais uniquement s'il existe plusieurs threads à l'intérieur du processus. Dans les applications NodeJS, le flux est un. PM2 est en mesure de vous aider dans cette situation et de répartir la charge entre plusieurs cœurs de processeur. Toujours avec une seule commande:

 pm2 start app.js -i max 


Dans ce cas, le paramètre max correspond au nombre de cœurs de processeur. C'est-à-dire 8 processus distincts seront créés pour le processeur à 8 cœurs. Vous pouvez également définir -1 au lieu de max, puis le nombre de processus correspondra au nombre de cœurs moins 1 . Tout le charme est que les connexions HTTP (S) / Websocket / TCP / UDP seront également réparties entre ces processus. Pourquoi pas une mise à l'échelle horizontale? Vous pouvez en savoir plus sur le clustering dans PM2 ici - PM2 Cluster Mode .

cluster_mode

Vous pouvez exécuter autant de processus que vous le souhaitez, mais il est néanmoins recommandé de respecter la recommandation «un processus par cœur».

Le respect de la mémoire


Lors du développement en PHP, j'ai rencontré une fois un problème. En raison de l'inexpérience, il a inconsciemment posé un bug dans le moteur du système, à cause duquel, dans certaines conditions, les processus ont commencé à consommer trop de RAM. En plus de cela, le processeur était chargé, à cause de quoi la machine virtuelle venait de raccrocher et je n'y avais pas du tout accès.
Comme le savent les développeurs PHP, en PHP-FPM, vous pouvez spécifier le type de distribution des processus (si vous ne le saviez pas soudainement, alors en PHP-FPM un nouveau processus est créé pour chaque nouvelle demande) - statique, lorsque les seuils minimum et maximum sont définis, et dynamique - allocation de la quantité autant de grands processus que nécessaire. Que se passera-t-il dans PM2 si vous démarrez 8 processus et que tous commencent à consommer beaucoup de mémoire? Et PM2 est capable de résoudre ce problème - avec un seul paramètre sur la ligne de commande:

 # Set memory threshold for app reload pm2 start app.js -i max --max-memory-restart <200MB> 


Chaque fois que la limite de mémoire est atteinte, PM2 redémarre automatiquement le processus. La distribution de mémoire est plus facile que les processus, n'est-ce pas? 8 processus * 200 mégaoctets = 1,6 gigaoctets. Mathématiques de deuxième classe.

En plus de redémarrer le processus, vous pouvez également configurer le redémarrage après un intervalle de temps N. Je n'ai pas encore compris dans quels cas cela peut être utile, mais n'hésitez pas à me signaler quelques exemples dans les commentaires :)

Et si je redémarre la machine virtuelle?


Surprise-surprise! PM2 résout également ce problème pour vous. Toujours avec pas plus d'une seule commande dans la console:

 pm2 startup 


PM2 générera un script qui déclenchera tous les processus nécessaires au démarrage du système d'exploitation. Cependant, vous devez être vigilant - lors de la mise à niveau de la version de Node.JS, tout peut se casser. Pour éviter cela, après une mise à niveau vers la nouvelle version de Node.JS réussie, exécutez pm2 unstartup et pm2 startup . Vous pouvez en savoir plus à ce sujet sur le lien - PM2 Startup Script Generator .

Est-il nécessaire de redémarrer les clusters manuellement lors des modifications?


Bien sûr que non! Eh bien, plus précisément, vous pouvez bien sûr redémarrer l'application manuellement, mais pourquoi? Automatisez tout ce que vous pouvez et que la force vous accompagne!

 pm2 start env.js --watch --ignore-watch="node_modules" 


Vous pouvez l'utiliser lors de la fusion d'une branche principale dans un référentiel local avec une branche principale d'un référentiel distant. Dans mon projet parallèle, cela se fait simplement - git pull origin master && npm run build . Lors de la modification de fichiers dans les dossiers serveur / build et client / build , les processus seront automatiquement redémarrés. Je comprends que c'est une fonctionnalité très simple et qu'elle ne mérite même pas d'être mentionnée dans ce texte. Je vais le diluer avec quelque chose de sérieux et écrire que si vous utilisez le clustering, tous les processus seront redémarrés à leur tour. Oui, afin qu'au moins l'un d'entre eux soit toujours disponible. Il s'agit d'un déploiement sans temps d'arrêt!

Et vous ne pouvez pas redémarrer les processus. Il y a un rechargement pour cela (quelque chose de similaire au rechargement de nginx):

 pm2 reload all 


Trop d'équipes! En général, je préfère les configs


Je suis déjà ennuyé de trouver des phrases drôles, donc c'est simple et banal: il y a un fichier d'écosystème. Les formats pris en charge sont JSON, YAML et JS. Par exemple, lorsque vous devez surveiller des fichiers dans les dossiers serveur et client :

 module.exports = { apps: [{ script: "app.js", watch: ["server", "client"], env_production : { "NODE_ENV": "production" } }] } 


Pour plus d'informations, consultez le lien - DĂ©claration d'application PM2 .

Et mĂŞme la surveillance l'est!


Et pas un. Choisissez celui que vous aimez le plus. Vous pouvez surveiller dans la console avec la commande:

 pm2 monit 




Ou utilisez la version de surveillance Web complète:



Bien sûr, vous ne me croirez pas, mais il est installé et lancé avec une seule commande:

 pm2 plus 


Et bien plus encore ...


Prise en charge déclarée de Heroku et Docker, incrémentation automatique des ports avec la possibilité de transférer vers process.env (lorsque vous devez exécuter chaque processus sur un port séparé), le lancement de plusieurs instances PM2 dans le même système d'exploitation, la présence d'une API logicielle et la possibilité d'exécuter des scripts Bash et Python diabolisés!

J'ai probablement manqué quelque chose d'autre d'important ou d'intéressant, que vous pouvez toujours me rappeler dans les commentaires. J'espère que vous avez pu apprendre quelque chose de nouveau grâce à cet article.

Source: https://habr.com/ru/post/fr480670/


All Articles