Vor ein paar Stunden habe ich eine Debatte darüber begonnen, dass Node.JS für große Projekte zu langsam ist und Golang, Rust, PHP usw. vorziehen sollte. Das Hauptargument der Gegenseite in diesem Streit war die Tatsache, dass JavaScript ein Singlethread ist. Angeblich ruht die Leistung bei der Entwicklung einer Anwendung einfach auf dieser Einfachheit und es kann nichts mehr getan werden - schreiben Sie es einfach in einer anderen Sprache. Bei NodeJS sieht es jedoch ein bisschen besser aus, als es auf den ersten Blick scheint. Bevor wir uns mit diesem Thema befassen, möchte ich erklären, dass ich das Recht jedes Entwicklers respektiere, die Programmiersprache zu verwenden, die ihm gefällt und die er für eine bestimmte Aufgabe für vorzuziehen hält.
Nachdem ich bei Habr nach dem Schlüsselwort „PM2“ gesucht habe, habe ich keinen Artikel gefunden, der diesem Prozessmanager gewidmet ist. Nur einzelne Verweise in Artikeln anderer Benutzer. Ich war begeistert von der Idee, diese dunkle Ecke der Backend-Entwicklung auf Node.JS (von der viele Leute wissen, ja, ich bin mir dessen bewusst) aufzuholen und aufzuklären. Ich frage alle Interessierten unter Katze.
Ein paar Worte zu PM2 selbst
PM2 ist ein Open Source-Prozessmanager, der unter der AGPL-3.0-Lizenz lizenziert ist. Zum Zeitpunkt des Schreibens hat es laut NPM ~ 350.000 wöchentliche Downloads. Es wird hauptsächlich in Umgebungen verwendet, in denen Sie eine Anwendung auf NodeJS ausführen und diese vergessen müssen (Sie können sie auch in anderen Sprachen verwenden, aber dazu später mehr). Auf diese Weise können Sie die Anwendung in Clustern zusammenfassen und die Last flexibel auf die Prozessorkerne verteilen. Ein kleiner Ausschnitt aus
dem PM2-Repository auf GitHub :
PM2 ist ein Produktionsprozessmanager für Node.js-Anwendungen mit einem integrierten Lastenausgleich. Es ermöglicht Ihnen, Anwendungen für immer am Leben zu erhalten, sie ohne Ausfallzeiten neu zu laden und allgemeine Systemadministrationsaufgaben zu vereinfachen.
Bei der Entwicklung stoßen viele Neulinge auf ein Problem, wenn sie nach dem "Roll-out" der Anwendung auf dem Produktionsserver nicht wissen, wie sie "für immer" gestartet werden sollen. Sie schreiben
set NODE_ENV=production && node app.js
in die SSH-Konsole, alles ist in Ordnung, die Anwendung funktioniert. Schließen Sie die Konsole und die Anwendung funktioniert nicht mehr. StackOverflow-Frage -
Wie wird die Anwendung node.js dauerhaft ausgeführt? erzielte mehr als 237 Tausend Aufrufe für alle Zeit.
PM2 löst dieses Problem mit einem Befehl:
pm2 start app.js
Dieser Befehl "verteufelt" (vom englischen "daemonize") den NodeJS-Prozess, überwacht dessen Speicherverbrauch und berücksichtigt die Prozessorlast.
Zurück zu unseren Widdern
Wenn die Last auf dem Backend zunimmt, muss es skaliert werden - sowohl vertikal als auch horizontal -, für wen es unter den gegebenen Umständen günstiger ist. Wie wir wissen, kann ein Prozess mehrere Prozessorkerne verwenden, jedoch nur, wenn sich mehrere Threads im Prozess befinden. In NodeJS-Anwendungen ist der Fluss eins. PM2 kann in dieser Situation Abhilfe schaffen und die Last auf mehrere Prozessorkerne verteilen. Immer noch mit nur einem Befehl:
pm2 start app.js -i max
In diesem Fall entspricht der Parameter
max der Anzahl der Prozessorkerne. Das heißt Für den 8-Core-Prozessor werden 8 separate Prozesse erstellt. Sie können auch
-1 anstelle von
max einstellen
, und dann entspricht die Anzahl der Prozesse der
Anzahl der Kerne
minus 1 . Der ganze Reiz ist, dass HTTP (S) / Websocket / TCP / UDP-Verbindungen gleichmäßig zwischen diesen Prozessen verteilt werden. Warum nicht horizontal skalieren? Weitere Informationen zum Clustering in PM2 finden Sie hier -
PM2-Cluster-Modus .

Sie können beliebig viele Prozesse ausführen, es wird jedoch empfohlen, die Empfehlung „Ein Prozess pro Kern“ einzuhalten.
Respekt für das Gedächtnis
Bei der Entwicklung in PHP bin ich einmal auf ein Problem gestoßen. Aufgrund von Unerfahrenheit hat er unbewusst einen Fehler in der System-Engine verursacht, aufgrund dessen Prozesse unter bestimmten Umständen zu viel RAM zu fressen begannen. Außerdem wurde der Prozessor geladen, wodurch die virtuelle Maschine gerade auflegte und ich überhaupt keinen Zugriff darauf hatte.
Wie PHP-Entwickler wissen, können Sie in PHP-FPM die Art der Verteilung von Prozessen festlegen (wenn Sie es plötzlich nicht wussten, wird in PHP-FPM für jede neue Anforderung ein neuer Prozess erstellt) - statisch, wenn die minimalen und maximalen Schwellenwerte festgelegt werden, und dynamisch - Zuweisung von wie viel so viele große Prozesse wie nötig. Was passiert in PM2, wenn Sie 8 Prozesse starten und alle viel Speicher verbrauchen? Und PM2 kann dieses Problem lösen - mit nur einem Parameter in der Befehlszeile:
# Set memory threshold for app reload pm2 start app.js -i max --max-memory-restart <200MB>
Jedes Mal, wenn das Speicherlimit erreicht ist, startet PM2 den Prozess automatisch neu. Das Verteilen von Speicher ist einfacher als Prozesse, nicht wahr? 8 Prozesse * 200 Megabyte = 1,6 Gigabyte. Mathematik der zweiten Klasse.
Zusätzlich zum Neustart des Prozesses können Sie auch einen Neustart nach einem Zeitintervall von N konfigurieren. Ich habe noch nicht herausgefunden, in welchen Fällen dies nützlich sein kann, kann mich aber gerne auf einige Beispiele in den Kommentaren hinweisen :)
Und wenn ich die virtuelle Maschine neu starte?
Überraschung-Überraschung! PM2 löst auch dieses Problem für Sie. Immer noch mit nicht mehr als einem einzigen Befehl in der Konsole:
pm2 startup
PM2 generiert ein Skript, das beim Start des Betriebssystems alle erforderlichen Prozesse auslöst. Sie sollten jedoch wachsam sein - beim Upgrade der Version von Node.JS kann alles kaputt gehen. Um dies zu vermeiden, führen Sie nach dem erfolgreichen Upgrade auf die neue Version von Node.JS
pm2 unstartup
und
pm2 startup
. Mehr dazu
erfahren Sie unter dem Link -
PM2 Startup Script Generator .
Müssen die Cluster bei Änderungen manuell neu gestartet werden?
Natürlich nicht! Genauer gesagt, Sie können die Anwendung natürlich manuell neu starten, aber warum? Automatisieren Sie alles, was Sie können und wollen, dass die Macht mit Ihnen kommt!
pm2 start env.js --watch --ignore-watch="node_modules"
Sie können dies verwenden, wenn Sie eine Hauptverzweigung in einem lokalen Repository mit einer Hauptverzweigung aus einem Remote-Repository zusammenführen. In meinem Nebenprojekt geschieht dies einfach -
git pull origin master && npm run build
. Wenn Sie Dateien in den Ordnern
server / build und
client / build ändern, werden die Prozesse automatisch neu gestartet. Ich verstehe, dass dies ein sehr einfaches Feature ist und es nicht einmal verdient, in diesem Text erwähnt zu werden. Ich werde es mit etwas Ernstem verdünnen und schreiben, dass, wenn Sie Clustering verwenden, alle Prozesse der Reihe nach neu gestartet werden. Ja, damit immer mindestens einer verfügbar ist. Dies ist eine Bereitstellung ohne Ausfallzeiten!
Und Sie können nicht Prozesse neu starten. Hierfür gibt es ein Reload (ähnlich wie bei nginx reload):
pm2 reload all
Zu viele Teams! Im Allgemeinen bevorzuge ich Configs
Mir ist es schon langweilig, lustige Sätze zu finden. Es ist einfach und banal: Es gibt eine Ökosystemdatei. Unterstützte Formate sind JSON, YAML und JS. Wenn Sie beispielsweise Dateien in den
Server- und Clientordnern überwachen müssen:
module.exports = { apps: [{ script: "app.js", watch: ["server", "client"], env_production : { "NODE_ENV": "production" } }] }
Weitere Informationen finden Sie unter dem Link -
PM2 Application Declaration .
Und selbst die Überwachung ist!
Und nicht einer. Wählen Sie die aus, die Ihnen am besten gefällt. Sie können in der Konsole Folgendes überwachen:
pm2 monit

Oder verwenden Sie die vollständige webbasierte Überwachungsversion:

Sie werden mir natürlich nicht glauben, aber es wird mit
einem Befehl installiert und gestartet:
pm2 plus
Und vieles mehr ...
Erklärte Unterstützung für Heroku und Docker, automatische Port-Inkrementierung mit der Fähigkeit, auf
process.env
zu übertragen (wenn Sie jeden Prozess auf einem separaten Port ausführen müssen), das Starten mehrerer PM2-Instanzen innerhalb desselben Betriebssystems, das Vorhandensein einer Software-API und die Fähigkeit, dämonisierte Bash- und Python-Skripte auszuführen!
Ich habe wahrscheinlich etwas anderes Wichtiges oder Interessantes verpasst, woran Sie mich in den Kommentaren immer erinnern können. Ich hoffe, dass Sie aus diesem Artikel etwas Neues lernen konnten.