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

12

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

[rails@server ~]$ 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

[rails@server ~]$ 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 ...

[rails@server ~]$ sudo systemctl enable NodeJSserver
[rails@server ~]$ sudo systemctl start NodeJSserver
[rails@server ~]$
[rails@server ~]$
[rails@server ~]$ forever list
info:    No forever processes running
[rails@server ~]$
[rails@server ~]$
[rails@server ~]$ 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?

Dave
quelle
journalctl -u nodejssollte Ihnen eine aussagekräftigere Fehlermeldung geben.
Federico klez Culloca
Ich erhalte die Meldung "Es wurden keine Journaldateien gefunden."
Dave
sudo journalctl sollte funktionieren. Überprüfen Sie auch in start.sh, ob die Ausgabeprotokolldateien an eine andere Stelle umgeleitet werden.
Rogerdpack

Antworten:

13

Ihr Dienst ist Type=in diesem [Service]Abschnitt nicht angegeben , es wird also systemddavon ausgegangen , dass Sie dies gemeint haben Type=simple.

Das bedeutet systemd, dass der Prozess, mit dem gestartet wurde ExecStart=, so lange ausgeführt wird, wie der Dienst ausgeführt wird. Aber es sieht so aus, als ob Sie start.shnur einen Befehl ausführen und dann beenden. Das ist der foreverBefehl : forever startStartet den Zielbefehl als Daemon oder mit anderen Worten im Hintergrund. Sobald der forever startBefehl abgeschlossen ist, wird die ausgeführte Shell beendet start.sh.

Zu diesem Zeitpunkt wird systemddieser Dienst als fehlgeschlagen betrachtet. Warten Sie, die für diesen Dienst zugewiesene Kontrollgruppe enthält noch einen laufenden Prozess. "Also", denkt systemd, "ist es nicht nur gescheitert, sondern hat auch ein Chaos hinter sich gelassen. Das kann man nicht haben." Da weder KillMode=noch KillSignal=angegeben, werden systemddie Standardeinstellungen fortgesetzt und ein SIGTERM für alle verbleibenden Prozesse in dieser Kontrollgruppe gesendet. Wenn diese nicht rechtzeitig beendet werden, wird ein SIGKILL angezeigt. Danach ist Ihr tatsächlicher NodeJS-Prozess garantiert tot.

Wie man es repariert

Da der Befehl, mit dem Sie ausgeführt werden, beendet ExecStart=wird, sobald der eigentliche Server gestartet wird, können Sie die Standardeinstellung nicht verwenden Type=simple. Sie müssen einen anderen Diensttyp angeben.

Sie könnten die verwenden Type=forking. Bei diesem Typ wird man systemd.servicedie Verwendung einer PIDFile=Option empfohlen. Wenn Ihr NodeJS-Server also eine PID-Datei für sich selbst erstellt (oder Sie dem foreverBefehl Optionen hinzufügen , damit er eine für ihn erstellt), sollten Sie systemdwissen, wo sich diese befindet.

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

Wenn Type=forkingbei Ihnen nicht funktioniert, dann können Sie angeben , Type=oneshotmit RemainAfterExit=yes.

Das macht systemdführen Sie einfach das ExecStart=Kommando , wenn der Dienst starten und ExecStop=wenn es zu stoppen, und was sonst noch nicht.

systemdIch werde mich jedoch immer noch daran erinnern, ob der Dienst zuletzt in einem gestoppten oder gestarteten Zustand eingestellt 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 Möglichkeit besteht darin, den foreverBefehl vollständig zu überspringen und systemdden NodeJS-Prozess neu zu starten. In diesem Fall nodejs.servicewäre Ihre gesamte 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 angeben RestartSec=5, dass vor dem Neustart des Dienstes ein 5-Sekunden-Ruhezustand angegeben werden soll, wenn der Dienst unerwartet beendet wird, um zu vermeiden, dass die Systemressourcen durch häufige Neustartversuche belastet werden, wenn Ihr Dienst aus irgendeinem Grund unmittelbar nach dem Neustart weiterhin ausfällt. (Der Standardwert RestartSec=ist 100 ms.)

Wenn Sie möchten, dass der Dienst neu gestartet wird, wenn er bestimmte Exit-Statuswerte zurückgibt, bei anderen jedoch davon ausgeht, dass er bei anderen fehlgeschlagen ist, gibt es auch dafür Optionen.

telcoM
quelle
Ich hatte einen Dienst, der nicht gestoppt wurde und nicht richtig gestartet wurde (er wird gestartet, aber der systemctl-Prozess wird nie beendet). Ich möchte nur hinzufügen, dass ich in meinem Fall nur Restart=alwaysmeine .service-Konfigurationsdatei hinzufügen musste.
Andy Forceno