Estoy usando CentOS 7. ¿Cómo puedo averiguar por qué un servicio no se inicia? He creado este servicio
[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
El archivo apunta a esto
[rails@server ~]$ cat /home/rails/NodeJSserver/start.sh
#!/bin/bash
forever start /home/rails/NodeJSserver/server.js
Puedo ejecutar este archivo muy bien por sí mismo. Pero cuando intento ejecutarlo como parte del servicio, noto que mi servidor nodeJS no está iniciado. Incluso cuando verifico "sudo systemctl --state = falló", no veo ningún error ...
[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'.
¿Cómo puedo averiguar por qué mi servicio no pudo iniciarse?
journalctl -u nodejs
debería darte un mensaje de error más significativo.Respuestas:
Su servicio no se ha
Type=
especificado en la[Service]
sección, por lo que sesystemd
supone que quiso decirType=simple
.Eso significa
systemd
que esperará que el proceso que se inicióExecStart=
continúe ejecutándose mientras se ejecute el servicio. Pero parece questart.sh
solo ejecuta un comando y luego sale. Ese es elforever
comando :forever start
inicia el comando de destino como un demonio, o en otras palabras, en segundo plano. Tan pronto como seforever start
complete el comando, sestart.sh
cerrará el shell en ejecución .En ese momento,
systemd
considera este servicio como fallido. Pero espere, el grupo de control asignado para ese servicio todavía tiene un proceso en ejecución. "Entonces", piensasystemd
, "no solo falló, sino que también dejó un desastre tras sí mismo. No puedo soportarlo". Como no hayKillMode=
niKillSignal=
especificado,systemd
continúa con sus valores predeterminados y envía un SIGTERM para los procesos restantes en ese grupo de control, y si no se detienen de manera oportuna, realiza un seguimiento con un SIGKILL. Después de eso, su proceso real de NodeJS estará muerto, garantizado.Como arreglarlo
Dado que el comando que ejecuta se
ExecStart=
cerrará tan pronto como se inicie el servidor real, no puede usar el predeterminadoType=simple
. Debe especificar otro tipo de servicio.Podrías usar el
Type=forking
. Con este tipo,man systemd.service
recomienda usar unaPIDFile=
opción, por lo que si su servidor NodeJS crea un archivo PID para sí mismo (o agrega opciones alforever
comando para que cree uno para él), debe informarsystemd
dónde estará.Si
Type=forking
no funciona para usted, puede especificarType=oneshot
conRemainAfterExit=yes
.Eso hace que
systemd
simplemente ejecute elExecStart=
comando al iniciar su servicio yExecStop=
al detenerlo, y no le importe nada más.systemd
aún así recordará si el servicio se configuró por última vez en estado detenido o iniciado. Entonces, si configura otro servicio para que dependa de este servicio, y luego detenga su servicio NodeJS manualmente, el otro servicio no se detendrá automáticamente y sin duda devolverá errores cuando no pueda usar su servicio NodeJS.La tercera opción es omitir el
forever
comando por completo y dejar desystemd
hacer el trabajo de reiniciar el proceso NodeJS. En ese caso, toda sunodejs.service
unidad sería:Podrías agregar otras opciones.
Por ejemplo, podría especificar
RestartSec=5
especificar un modo de suspensión de 5 segundos antes de intentar reiniciar el servicio si se muere inesperadamente, para evitar acaparar los recursos del sistema mediante intentos frecuentes de reinicio si su servicio sigue muriendo inmediatamente después de ser reiniciado por alguna razón. (ElRestartSec=
valor predeterminado es 100 ms.)O si desea que el servicio se reinicie si devuelve algunos valores de estado de salida específicos, pero considera que falló en otros, también hay opciones para eso.
fuente
Restart=always
a mi archivo de configuración .service.