01.072015

Node-JS Anwendungen mit PM2 managen

Heute pausieren wir unsere BDD-Serie, um einen Blick auf Node-JS zu werfen. Node-JS ist eine tolle Sprache um Webservices und andere inhärent asynchrone Anwendungen schnell umzusetzen. So ist der eigene URL-Shortener, Bilder-Minifier, oder die eigene Shoutbox schnell umgesetzt.

Für komplexere Dienste verweisen Node-Entwickler gerne auf die Unix-Philosophy "Do One Thing and Do It Well" - Gestalte jedes Programm so, dass es eine Aufgabe gut erledigt. So werden kleine Module, kleine Klassen und eben auch kleine Anwendungen hervorgehoben. Systeme die dieser Regel folgen sind meist trivial zu skalieren - wir starten einfach eine weitere Instanz des überforderten Dienstes.

Wie aber verwalte ich nun eine Anwendung, die sich aus vielen verschiedenen Prozessen zusammensetzt? PM2 (Process Manager 2) füllt die gefühlte Lücke

Besteht ein System aus verschiedenen Node-Anwendungen so müssen diese gestartet, überwacht, aktualisiert und vielleicht sogar skaliert werden. Während für Live-Systeme spezialisierte Lösungen sicherlich der bessere Ansatz sind, so ist besonders in Phasen aktiver Entwicklung PM2 der McGyver unter den Multifunktionstools. Im folgenden möchte ich mir eine Reihe an Features herauspicken und vorstellen und euch vielleicht für euer nächstes Node-Projekt etwas arbeit abnehmen:

PM2 installieren

npm i -g pm2

Wie bei den meisten in und für Node-JS geschriebenen Modulen ist die Installation direkt über npm möglich.

Starten von Node-Anwendungen

pm2 start index.js

Optional lässt sich der Prozess mittels --name 'Name der Anwendung' noch benennen. PM2 startet die Anwendung und startet sie gegebenenfalls neu, falls sich diese nicht sauber beendet. Ebenso analysiert PM2 den Speicherverbrauch der Anwendung und startet diese neu, falls ein Speicherleck erkannt wird. Dieses Verhalten ist konfigurierbar

pm2_start

Monitoring

pm2 monit

Durch den monit (kurz 'm') Befehl wird eine sich automatisch aktualisierende übersicht aller gemanageten Prozesse angezeigt

pm2_monit

Logging

pm2 logs [id|name]

PM2 loggt die Ausgabe aller Prozesse. Diese können mittels des Befehls logs angezeigt werden. Durch die übergabe einer Id oder des Namens können auch nur die Logs eines laufenden Prozesses angezeigt werden. PM2 kümmert sich um eine automatisches "Log-Rotate". 

Clustering

pm2 start index.js -i <anzahl>

Durch den Parameter -i entweder mit einer festen Anzahl oder max als Argument werden eine feste Anzahl an Instanzen eines Prozesses gestartet. Wird als Anzahl max übergeben, so werden entsprechend der Zahl an Rechenkernen der CPU Instanzen gestartet. Clustering ist hilfreich, wenn alle Ressourcen des Systems genutzt werden sollen.

pm2_cluster

Die Anzahl der Instanzen eines Prozesses der im Cluster-Modus gestartet wurde lässt sich über den Befehl scale im laufenden Betrieb ändern

pm2_scale_up

Live-Reload

pm2 start index.js --watch

Das letzte Feature, dass ich vorstellen möchte ist für die Entwicklung von Node-Anwendungen extrem hilfreich. Alle Prozesse die mit dem Parameter --watch gestartet werden starten sie bei Dateiänderungen innerhalb des Anwendungsverzeichnisses automatisch neu. Somit ist es nicht mehr nötig von Hand Prozesse, deren Quellcode gerade aktiv bearbeitet wird bei jeder Änderung manuell neuzustarten.

Weitere tolle Funktionen

PM2 besitzt noch eine Reihe anderer nützlicher Funktionen, die ich nur knapp auflisten möchte:

  • Startup-Script Generierung
  • Graceful- (Rolling-) Restart von Prozessen - neustart bei dem immer wenigstens eine Instanz der Anwendung erreichbar bleibt
  • Integration mit git um Beispielsweise die Anwendung auf den letzten Commit zurückzusetzen
  • Garbage Collection erzwingen
  • System-Signale an Prozesse schicken
  • ...

Für den produktiv Einsatz ist PM2 möglicherweise nicht das richtige, aber während der Anwendungsentwicklung sind die vielen kleinen und gut durchdachten Tools hilfreich und ersparen Entwicklern einiges an Zeit.

Somit bleibt mir nur noch frohes Entwickeln zu wünschen. Wir sehen uns dann beim nächsten mal zum Abschluss der BDD-Reihe.