Jak dowiedzieć się, dlaczego moja usługa systemctl nie uruchomiła się na CentOS 7?

12

Korzystam z CentOS 7. Jak dowiedzieć się, dlaczego usługa się nie uruchamia? Stworzyłem tę usługę

[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

Plik wskazuje na to

[rails@server ~]$ cat /home/rails/NodeJSserver/start.sh
#!/bin/bash

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

Mogę sam uruchomić ten plik. Ale kiedy próbuję uruchomić go jako część usługi, zauważam, że mój serwer nodeJS nie został uruchomiony. Nawet gdy zaznaczę „sudo systemctl --state = failed”, nie widzę żadnych błędów ...

[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'.

Jak dowiedzieć się, dlaczego moja usługa się nie uruchomiła?

Dave
źródło
journalctl -u nodejspowinien dać ci bardziej znaczący komunikat o błędzie.
Federico klez Culloca,
Pojawia się komunikat „Nie znaleziono plików dziennika”.
Dave
sudo journalctl powinien działać. Również w pliku start.sh sprawdź, czy przekierowuje wyjściowe pliki dziennika do innego miejsca.
rogerdpack,

Odpowiedzi:

13

Twoja usługa nie została Type=określona w tej [Service]sekcji, więc systemdzakładasz, że miałeś na myśli Type=simple.

Oznacza to systemd, że proces, który został uruchomiony, ExecStart=będzie działał tak długo, jak długo usługa będzie działać. Ale wygląda na to, że start.shuruchamiasz tylko jedno polecenie, a następnie kończy działanie. To jest polecenia : uruchamia polecenie docelowy jako demon, czyli innymi słowy, w tle. Po zakończeniu wykonywania polecenia uruchomiona powłoka zostanie zamknięta.foreverforever startforever startstart.sh

W tym momencie systemduważa tę usługę za nieudaną. Ale czekaj, grupa kontrolna przypisana do tej usługi wciąż ma w sobie uruchomiony proces. „A więc”, myśli systemd, „nie tylko zawiodło, ale także po sobie popsuło. Nie mogę tego mieć”. Ponieważ nie ma żadnej KillMode=ani KillSignal=określonej, systemdkontynuuje działanie z ustawieniami domyślnymi i wysyła SIGTERM dla wszystkich pozostałych procesów w tej grupie kontrolnej, a jeśli nie zatrzymają się w odpowiednim czasie, następuje SIGKILL. Po tym, twój faktyczny proces NodeJS będzie martwy, gwarantowany.

Jak to naprawić

Ponieważ polecenie, które uruchomisz ExecStart=, zakończy działanie natychmiast po uruchomieniu rzeczywistego serwera, nie możesz użyć wartości domyślnej Type=simple. Musisz określić inny typ usługi.

Możesz użyć Type=forking. W przypadku tego typu man systemd.servicezaleca użycie PIDFile=opcji, więc jeśli serwer NodeJS utworzy dla siebie plik PID (lub dodasz opcje do foreverpolecenia, aby go utworzyć), powinieneś poinformować systemd, gdzie on będzie.

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

Jeśli Type=forkingto nie działa, możesz określić za Type=oneshotpomocą RemainAfterExit=yes.

To sprawia, że systemdpo prostu uruchom ExecStart=polecenie podczas uruchamiania usługi i ExecStop=podczas jej zatrzymywania, i nie przejmuj się niczym innym.

systemdnadal będzie pamiętał, czy usługa była ostatnio ustawiona w stanie zatrzymanym czy uruchomionym. Jeśli więc ustawisz inną usługę jako zależną od tej usługi, a następnie ręcznie zatrzymasz usługę NodeJS, inna usługa nie zatrzyma się automatycznie i bez wątpienia zwróci błędy, gdy nie będzie mogła korzystać z usługi NodeJS.


Trzecią opcją jest forevercałkowite pominięcie polecenia i systemdwykonanie zadania ponownego uruchomienia procesu NodeJS. W takim przypadku cała twoja nodejs.servicejednostka byłaby:

[Unit]
Description=nodejs server

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

[Install]
WantedBy=multi-user.target

Możesz dodać inne opcje.

Na przykład możesz określić, RestartSec=5aby określić 5-sekundowy sen przed próbą ponownego uruchomienia usługi, jeśli niespodziewanie umrze, aby uniknąć blokowania zasobów systemowych przez częste próby ponownego uruchomienia, jeśli twoja usługa umiera natychmiast po ponownym uruchomieniu z jakiegoś powodu. (Wartość domyślna RestartSec=to 100 ms.)

Lub jeśli chcesz zrestartować usługę, jeśli zwróci ona pewne określone wartości statusu wyjścia, ale uważasz, że nie powiodła się na innych, istnieją również takie opcje.

telcoM
źródło
Miałem usługę, która się nie zatrzymywała i nie uruchamiała poprawnie (uruchamia się, ale proces systemctl nigdy się nie kończy). Chcę tylko dodać, że w moim przypadku wszystko, co musiałem zrobić, to dodać Restart=alwaysdo mojego pliku konfiguracyjnego .service.
Andy Forceno,