web-dev-qa-db-fra.com

Comment savoir pourquoi mon service systemctl n'a pas démarré sur CentOS 7?

J'utilise CentOS 7. Comment savoir pourquoi un service ne démarre pas? J'ai créé ce service

[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

Le fichier pointe

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

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

Je peux exécuter ce fichier très bien par lui-même. Mais lorsque j'essaie de l'exécuter dans le cadre du service, je remarque que mon serveur nodeJS n'est pas démarré. Même lorsque je vérifie "Sudo systemctl --state = failed", je ne vois aucune erreur ...

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

Comment savoir pourquoi mon service n'a pas pu démarrer?

12
Dave

Votre service n'a pas de Type= spécifié dans le [Service] section, donc systemd suppose que vous vouliez dire Type=simple.

Cela signifie que systemd attendra le processus démarré avec ExecStart= pour continuer à fonctionner tant que le service est en cours d'exécution. Mais il ressemble à votre start.sh n'exécute qu'une seule commande puis quitte. C'est la commande forever : forever start démarre la commande cible en tant que démon, ou en d'autres termes, en arrière-plan. Aussi tôt que le forever start la commande se termine, le shell exécutant start.sh va sortir.

À ce stade, systemd considère que ce service a échoué. Mais attendez, le groupe de contrôle affecté à ce service a toujours un processus en cours. "Donc," pense systemd, "non seulement il a échoué, mais il a également laissé un gâchis après lui-même. Puisqu'il n'y a pas de KillMode= ni KillSignal= spécifié, systemd continue avec ses valeurs par défaut et envoie un SIGTERM pour tous les processus restants dans ce groupe de contrôle, et s'ils ne s'arrêtent pas en temps opportun, suit avec un SIGKILL. Après cela, votre processus NodeJS réel sera mort, garanti.

Comment le réparer

Depuis la commande que vous exécutez avec ExecStart= se fermera dès que le serveur réel sera démarré, vous ne pouvez pas utiliser la valeur par défaut Type=simple. Vous devez spécifier un autre type de service.

Vous pouvez utiliser le Type=forking. Avec ce type, man systemd.service recommande d'utiliser un PIDFile= option, donc si votre serveur NodeJS crée un fichier PID pour lui-même (ou si vous ajoutez des options à la commande forever pour lui en créer une), vous devez laisser systemd savoir où il sera.

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

Si Type=forking ne fonctionne pas pour vous, vous pouvez alors spécifier Type=oneshot avec RemainAfterExit=yes.

Cela fait que systemd lance simplement le ExecStart= commande lors du démarrage de votre service et ExecStop= lorsque vous l'arrêtez, et ne vous souciez de rien d'autre.

systemd se souviendra toujours si le service a été défini pour la dernière fois à l'état arrêté ou démarré. Donc, si vous définissez un autre service pour dépendre de ce service, puis arrêtez votre service NodeJS manuellement, l'autre service ne s'arrêtera pas automatiquement et renverra sans aucun doute des erreurs lorsqu'il ne pourra pas utiliser votre service NodeJS.


La troisième option consiste à ignorer complètement la commande forever et à laisser systemd faire le travail de redémarrage du processus NodeJS. Dans ce cas, l'ensemble de votre nodejs.service l'unité serait:

[Unit]
Description=nodejs server

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

[Install]
WantedBy=multi-user.target

Vous pouvez ajouter d'autres options.

Par exemple, vous pouvez spécifier RestartSec=5 pour spécifier une mise en veille de 5 secondes avant de tenter de redémarrer le service en cas de mort inattendue, pour éviter de surcharger les ressources système par de fréquentes tentatives de redémarrage si votre service continue de mourir immédiatement après avoir été redémarré pour une raison quelconque. (Le défaut RestartSec= la valeur est de 100 ms.)

Ou si vous souhaitez que le service soit redémarré s'il renvoie des valeurs de statut de sortie spécifiques, mais que vous pensez qu'il a échoué sur d'autres, il existe également des options pour cela.

13
telcoM