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?
journalctl -u nodejs
devrait vous donner un message d'erreur plus significatif.Réponses:
Votre service n'a pas
Type=
spécifié dans la[Service]
section,systemd
suppose donc que vous vouliez direType=simple
.Cela signifie
systemd
que le processus démarréExecStart=
continuera de fonctionner tant que le service est en cours d'exécution. Mais il semble que votrestart.sh
ne lance qu'une seule commande, puis se termine. C'est laforever
commande :forever start
démarre la commande cible en tant que démon, ou en d'autres termes, en arrière-plan. Dès que laforever start
commande est terminée, le shell en cours d'exécutionstart.sh
se termine .À 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-t-ilsystemd
, "non seulement il a échoué, mais il a également laissé un gâchis après lui-même. Ça ne peut pas avoir ça." Puisqu'il n'y a aucunKillMode=
niKillSignal=
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
Étant donné que la commande que vous exécutez
ExecStart=
se termine dès que le serveur réel est démarré, vous ne pouvez pas utiliser la valeur par défautType=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 unePIDFile=
option, donc si votre serveur NodeJS crée un fichier PID pour lui-même (ou si vous ajoutez des options à laforever
commande pour en créer un), vous devezsystemd
indiquer où il se trouvera.Si
Type=forking
cela ne fonctionne pas pour vous, vous pouvez spécifierType=oneshot
avecRemainAfterExit=yes
.Cela fait
systemd
simplement exécuter laExecStart=
commande au démarrage de votre service etExecStop=
à son arrêt, sans vous soucier d'autre chose.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
forever
complètement la commande et à laissersystemd
le travail de redémarrage du processus NodeJS. Dans ce cas, votrenodejs.service
unité entière serait:Vous pouvez ajouter d'autres options.
Par exemple, vous pouvez spécifier
RestartSec=5
de spécifier un sommeil de 5 secondes avant de tenter de redémarrer le service s'il meurt de façon inattendue, pour éviter de monopoliser 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. (LaRestartSec=
valeur par défaut est 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.
la source
Restart=always
à mon fichier de configuration .service.