it-swarm.com.de

Wie finde ich heraus, warum mein systemctl-Dienst unter CentOS 7 nicht gestartet wurde?

Ich verwende CentOS 7. Wie finde ich heraus, warum ein Dienst nicht gestartet werden kann? Ich habe diesen Service erstellt

[[email protected] ~]$ Sudo cat /usr/lib/systemd/system/nodejs.service
[Unit]
Description=nodejs server

[Service]
User=Rails
Group=Rails
ExecStart=/home/Rails/NodeJSserver/start.sh
ExecStop=/home/Rails/NodeJSserver/stop.sh

[Install]
WantedBy=multi-user.target

Die Datei zeigt darauf

[[email protected] ~]$ cat /home/Rails/NodeJSserver/start.sh
#!/bin/bash

forever start /home/Rails/NodeJSserver/server.js

Ich kann diese Datei ganz gut alleine ausführen. Wenn ich jedoch versuche, es als Teil des Dienstes auszuführen, stelle ich fest, dass mein nodeJS-Server nicht gestartet ist. Selbst wenn ich "Sudo systemctl --state = failed" überprüfe, sehe ich keine Fehler ...

[[email protected] ~]$ Sudo systemctl enable NodeJSserver
[[email protected] ~]$ Sudo systemctl start NodeJSserver
[[email protected] ~]$
[[email protected] ~]$
[[email protected] ~]$ forever list
info:    No forever processes running
[[email protected] ~]$
[[email protected] ~]$
[[email protected] ~]$ Sudo systemctl --state=failed
  UNIT                           LOAD   ACTIVE SUB    DESCRIPTION
● nginx.service                  loaded failed failed The nginx HTTP and reverse proxy server
● systemd-sysctl.service         loaded failed failed Apply Kernel Variables
● systemd-vconsole-setup.service loaded failed failed Setup Virtual Console

LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB    = The low-level unit activation state, values depend on unit type.

3 loaded units listed. Pass --all to see loaded but inactive units, too.
To show all installed unit files use 'systemctl list-unit-files'.

Wie finde ich heraus, warum mein Dienst nicht gestartet werden konnte?

12
Dave

Ihr Dienst hat kein Type= Im Abschnitt [Service] Angegeben, daher geht systemd davon aus, dass Sie Type=simple Bedeuteten.

Das bedeutet, dass systemd erwartet, dass der mit ExecStart= Gestartete Prozess so lange ausgeführt wird, wie der Dienst ausgeführt wird. Aber es sieht so aus, als würde Ihr start.sh Nur einen Befehl ausführen und dann beenden. Das heißt der Befehl forever : forever start Startet den Zielbefehl als Daemon oder mit anderen Worten im Hintergrund. Sobald der Befehl forever start Abgeschlossen ist, wird die Shell mit start.sh Beendet.

Zu diesem Zeitpunkt betrachtet systemd diesen Dienst als fehlgeschlagen. Warten Sie, die für diesen Dienst zugewiesene Kontrollgruppe enthält noch einen laufenden Prozess. "Also", denkt systemd, "ist nicht nur gescheitert, sondern hat auch ein Chaos hinter sich gelassen. Das kann man nicht haben." Da weder KillMode= Noch KillSignal= Angegeben sind, setzt systemd seine Standardeinstellungen fort und sendet ein SIGTERM für alle verbleibenden Prozesse in dieser Kontrollgruppe, und wenn sie nicht gestoppt werden pünktlich mit einem SIGKILL. Danach ist Ihr tatsächlicher NodeJS-Prozess garantiert tot.

Wie man es repariert

Da der Befehl, den Sie mit ExecStart= Ausführen, beendet wird, sobald der eigentliche Server gestartet wird, können Sie den Standardwert Type=simple Nicht verwenden. Sie müssen einen anderen Diensttyp angeben.

Sie können den Type=forking Verwenden. Bei diesem Typ empfiehlt man systemd.service Die Verwendung einer Option PIDFile=. Wenn Ihr NodeJS-Server also eine PID-Datei für sich selbst erstellt (oder Sie dem Befehl forever Optionen hinzufügen, um sie zu erstellen eine dafür), sollten Sie systemd wissen lassen, wo es sein wird.

[Service]
Type=forking
PIDFile=/absolute/path/to/nodejs.pid
User=Rails
... <the rest as before>

Wenn Type=forking Für Sie nicht funktioniert, können Sie Type=oneshot Mit RemainAfterExit=yes Angeben.

Das führt dazu, dass systemd beim Starten Ihres Dienstes einfach den Befehl ExecStart= Und beim Beenden des Dienstes ExecStop= Ausführt und sich um nichts anderes kümmert.

systemd merkt sich jedoch immer noch, ob der Dienst zuletzt in einem gestoppten oder gestarteten Zustand gesetzt wurde. Wenn Sie also einen anderen Dienst so einstellen, dass er von diesem Dienst abhängt, und dann Ihren NodeJS-Dienst manuell beenden, wird der andere Dienst nicht automatisch beendet und gibt zweifellos Fehler zurück, wenn er Ihren NodeJS-Dienst nicht verwenden kann.


Die dritte Option besteht darin, den Befehl forever vollständig zu überspringen und systemd den Neustart des NodeJS-Prozesses ausführen zu lassen. In diesem Fall wäre Ihre gesamte nodejs.service - Einheit:

[Unit]
Description=nodejs server

[Service]
User=Rails
Group=Rails
ExecStart=/home/Rails/NodeJSserver/server.js
Restart=always

[Install]
WantedBy=multi-user.target

Sie können weitere Optionen hinzufügen.

Sie können beispielsweise RestartSec=5 Angeben, um einen Ruhezustand von 5 Sekunden anzugeben, bevor Sie versuchen, den Dienst neu zu starten, wenn er unerwartet ausfällt. So vermeiden Sie, dass die Systemressourcen durch häufige Neustartversuche belastet werden, wenn Ihr Dienst für einige sofort nach dem Neustart weiterhin ausfällt Grund. (Der Standardwert RestartSec= Ist 100 ms.)

Wenn Sie möchten, dass der Dienst neu gestartet wird, wenn bestimmte Exit-Statuswerte zurückgegeben werden, bei anderen jedoch ein Fehler aufgetreten ist, gibt es auch dafür Optionen.

13
telcoM