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?
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.
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.