Pm2 Prozess Manager Einführung
console.log('It´s time to code');
Hallo,
Heute möchte ich euch kurz den Prozessmanager PM2 vorstellen. Der mittels CLI Interface sehr komfortabel gesteuert werden kann.
Primäre Aufgaben eines Prozessmanagers:
- Automatischer Neustart der Anwendung nach einem Absturz
- Protokollierung im Fehlerfall
- Monitorring des Laufzeitverhaltens und der Ressourcennutzung
- Nachladen von Programmen ohne Ausfallzeit
- uvm.
PM2 ist primär für den Einsatz in einer Produktivumgebung gedacht um bei einen Absturz einer Anwendung diese neu zu starten und den Fehler in einem Logfile festzuhalten. Gerade in der Releasephase einer Anwendung ist es von großen Vorteil das nicht jedes mal die Anwendung von Hand neu gestartet werden muss wenn ein Fehler auftritt.
PM2 unterstützt eine breite Palette von folgenden Skriptsprachen:
- Javascript (Node.js)
- Python
- Ruby
- uvm.
Installation
PM2 lässt sich ganz einfach über den Node Packet Manager (npm) mit folgenden Befehl installieren:
$ sudo npm install -g pm2
Nach der Installation prüfen wir noch ob PM2 auch ordnungsgemäß installiert worden ist mit folgenden Befehl:
$ pm2
Und wir sollten folgende Ausgabe erhalten:
Basic Examples:
Start an app using all CPUs available + set a name :
$ pm2 start app.js -i 0 --name "api"
Restart the previous app launched, by name :
$ pm2 restart api
Stop the app :
$ pm2 stop api
Restart the app that is stopped :
$ pm2 restart api
Remove the app from the process list :
$ pm2 delete api
Kill daemon pm2 :
$ pm2 kill
Update pm2 :
$ npm install pm2@latest -g ; pm2 update
More examples in https://github.com/Unitech/pm2#usagefeatures
Deployment help:
$ pm2 deploy help
Erste Schritte mit PM2
Um einen Prozess über PM2 zu starten brauchen wir erst einmal ein kleines Skript. Dafür kopieren wir den unten angeführten Quellcode in einen Datei und geben ihr den Namen app.js.
var http = require('http');
var server = http.createServer(function (request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.end("Hello PM2\n");
console.log(response.statusCode + ' ' + response.statusMessage);
});
// Listen on port 8000, IP defaults to 127.0.0.1
server.listen(8000);
console.log("Server running at http://127.0.0.1:8000/");
//app.js
Anschließend starten wie das Skript mit PM2 mit folgenden Befehl:
$ pm2 start app.js --name "app"
[PM2] Spawning PM2 daemon with pm2_home=/home/dgrill/.pm2
[PM2] PM2 Successfully daemonized
[PM2] Starting /home/dgrill/Schreibtisch/TEMP/app.js in fork_mode (1 instance)
[PM2] Done.
┌──────────┬────┬──────┬───────┬────────┬─────────┬────────┬─────┬───────────┬──────────┐
│ App name │ id │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ watching │
├──────────┼────┼──────┼───────┼────────┼─────────┼────────┼─────┼───────────┼──────────┤
│ app │ 0 │ fork │ 20211 │ online │ 0 │ 0s │ 2% │ 20.0 MB │ disabled │
└──────────┴────┴──────┴───────┴────────┴─────────┴────────┴─────┴───────────┴──────────┘
Use `pm2 show <id|name>` to get more details about an app
Und sehen in der Ausgabe das der Prozess nun erfolgreich gestartet worden ist.
Sollte unser kleine Anwendung nun einen Fehler produzieren wird der Prozess automatisch von PM2 neu
gestartet und der restart counter erhöht. Des weiteren wird ein Eintrag im Error Log angelegt das Standardmässig unter linux im folgenden Verzeichnis zu finden ist (/home/user/.pm2/logs). Zusätzlich zum überwachen
und neustarten von Prozessen zeichnet PM2 auch alle Logmeldungen auf, die von der Applikation in die Standard Ausgabe geschrieben werden.
/home/user/.pm2
├── logs
│ ├── app-error-0.log
│ └── app-out-0.log
├── module_conf.json
├── pids
│ └── app-0.pid
├── pm2.log
├── pm2.pid
├── pub.sock
├── rpc.sock
└── touch
2 directories, 9 files
Log Einträge anzeigen
Um sich die aktuellen Logmeldungen des laufenden Prozess live anzusehen geben wir folgenden Befehl ein:
$ pm2 logs app
Und wir erhalten folgende Ausgabe:
[STREAMING] Now streaming realtime logs for [app] process
Rufen wir nun in unseren Browser folgenden Link auf http://localhost:8000/ und senden somit eine Anfrage an unsere Applikation. Werden die Logmeldungen in Echtzeit ausgegeben.
0|app | 200 OK
0|app | 200 OK
Starten von Prozesse via config.json
Sollen mehrere Anwendungen von PM2 überwacht werden bittet es sich an alle Prozesse in eine json Datei zusammen zu fassen. Somit können mehrere Prozesse mit einen Befehl von PM2 überwacht werden.
[
{
"script" : "/home/dgrill/Schreibtisch/TEMP/app/app.js",
"name" : "app",
"merge_logs" : true,
"log_date_format" : "YYYY-MM-DD HH:mm Z"
},
{
"script" : "/home/dgrill/Schreibtisch/TEMP/app_1/app_1.js",
"name" : "app_1",
"merge_logs" : true,
"log_date_format" : "YYYY-MM-DD HH:mm Z"
}
]
process.json
Das Starten der Anwendung folgt wie schon oben beschrieben über den Befehl pm2 start nur mit dem Unterschied das wir hier die config.json datei angeben.
$ pm2 start process.json
[PM2][WARN] Applications app, app_1 not running, starting...
[PM2] App [app] launched (1 instances)
[PM2] App [app_1] launched (1 instances)
┌──────────┬────┬──────┬──────┬────────┬─────────┬────────┬─────┬───────────┬──────────┐
│ App name │ id │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ watching │
├──────────┼────┼──────┼──────┼────────┼─────────┼────────┼─────┼───────────┼──────────┤
│ app │ 0 │ fork │ 2019 │ online │ 0 │ 0s │ 0% │ 17.2 MB │ disabled │
│ app_1 │ 1 │ fork │ 2024 │ online │ 0 │ 0s │ 0% │ 16.6 MB │ disabled │
└──────────┴────┴──────┴──────┴────────┴─────────┴────────┴─────┴───────────┴──────────┘
Use `pm2 show <id|name>` to get more details about an app
Neustarten der Prozesse
$ pm2 restart process.json
[PM2] Applying action restartProcessId on app [app](ids: 0)
[PM2] Applying action restartProcessId on app [app_1](ids: 1)
[PM2] [app](0) ✓
[PM2] [app_1](1) ✓
┌──────────┬────┬──────┬──────┬────────┬─────────┬────────┬─────┬───────────┬──────────┐
│ App name │ id │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ watching │
├──────────┼────┼──────┼──────┼────────┼─────────┼────────┼─────┼───────────┼──────────┤
│ app │ 0 │ fork │ 7131 │ online │ 0 │ 10s │ 0% │ 17.3 MB │ disabled │
│ app_1 │ 1 │ fork │ 7136 │ online │ 0 │ 10s │ 0% │ 15.2 MB │ disabled │
└──────────┴────┴──────┴──────┴────────┴─────────┴────────┴─────┴───────────┴──────────┘
Use `pm2 show <id|name>` to get more details about an app
Stoppen der Prozesse
$ pm2 stop process.json
[PM2] [app](0) ✓
[PM2] [app_1](1) ✓
┌──────────┬────┬──────┬─────┬─────────┬─────────┬────────┬─────┬────────┬──────────┐
│ App name │ id │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ watching │
├──────────┼────┼──────┼─────┼─────────┼─────────┼────────┼─────┼────────┼──────────┤
│ app │ 0 │ fork │ 0 │ stopped │ 0 │ 12 │ 0% │ 0 B │ disabled │
│ app_1 │ 1 │ fork │ 0 │ stopped │ 0 │ 12 │ 0% │ 0 B │ disabled │
└──────────┴────┴──────┴─────┴─────────┴─────────┴────────┴─────┴────────┴──────────┘
Use `pm2 show <id|name>` to get more details about an app
Der weitere große Vorteil von eine config.json datei ist das alle in diese enthalten Datei auf einmal gestartet/gestoppt oder neu gestartet werden können. Und somit auch Abhängigkeiten von Prozessen berücksichtigt werden können.
PM2 im produktiven Einsatz
Um nun PM2 produktiv einzusetzen müssen noch ein paar Grundeinstellungen vorgenommen werden. Als erstes müssen wie PM2 als dameon(bzw. Dienst) einrichten. Hierzu reicht uns erstmals folgender Befehl:
$ pm2 startup
[PM2] You have to run this command as root. Execute the following command:
sudo su -c "env PATH=$PATH:/home/unitech/.nvm/versions/node/v4.3/bin pm2 startup <distribution> -u <user> --hp <home-path>
PM2 erstellt durch diesen Befehl automatisch ein Startscript für unser System und mit dem Befehl aus der Ausgabe wird das Startscript für den Systemstart registriert.
[PM2] Spawning PM2 daemon with pm2_home=/root/.pm2
[PM2] PM2 Successfully daemonized
[PM2] Writing startup script in /etc/init.d/pm2-init.sh
[PM2] Making script booting at startup...
[PM2] -linux- Using the command:
su -c "chmod +x /etc/init.d/pm2-init.sh && update-rc.d pm2-init.sh defaults"
[PM2] Done.
[PM2] Now you can type
$ pm2 save
[PM2] To save the current process list at reboot or via pm2 update
Wurde das Startskript erfolgreich im System registriert erhalten wir noch den Hinweise den Befehl pm2 save auszuführen.
$ pm2 save
Und das sollte wir auch auf alle Fälle tun wenn wir alle aktuellen prozesse speichern wollen und somit sicherstellen das nach einen Systemneustart alle Prozesse gestartet werden. Sollten wir das Speichern der Prozesse vergessen wird nach einen Systemneustart von PM2 kein Prozess gestartet. PM2 save muss auch jedes mal ausgeführt werden wenn wir einen neuen Prozess hinzufügen.
console.log('See you !');
Mehr Informationen
Eine Sammlung der Wichtigsten PM2 Befehle
PM2 Kommandoreferenz
Die offiziele Dokumentation von PM2
PM2 Official Docs