debian - El supervisor no reinicia la mitad del tiempo
uwsgi systemd (2)
Estoy intentando implementar una aplicación Django usando Uwsgi y supervisor en una máquina que ejecuta Debian 8.1.
Cuando reinicio a través de sudo systemctl restart supervisor
, no se reinicia la mitad del tiempo.
$ root@host:/# systemctl start supervisor
Job for supervisor.service failed. See ''systemctl status supervisor.service'' and ''journalctl -xn'' for details.
$ root@host:/# systemctl status supervisor.service
● supervisor.service - LSB: Start/stop supervisor
Loaded: loaded (/etc/init.d/supervisor)
Active: failed (Result: exit-code) since Wed 2015-09-23 11:12:01 UTC; 16s ago
Process: 21505 ExecStop=/etc/init.d/supervisor stop (code=exited, status=0/SUCCESS)
Process: 21511 ExecStart=/etc/init.d/supervisor start (code=exited, status=1/FAILURE)
Sep 23 11:12:01 host supervisor[21511]: Starting supervisor:
Sep 23 11:12:01 host systemd[1]: supervisor.service: control process exited, code=exited status=1
Sep 23 11:12:01 host systemd[1]: Failed to start LSB: Start/stop supervisor.
Sep 23 11:12:01 host systemd[1]: Unit supervisor.service entered failed state.
Sin embargo, no hay nada en los registros de supervisor o uwsgi. Supervisor 3.0 se está ejecutando con esta configuración para uwsgi:
[program:uwsgi]
stopsignal=QUIT
command = uwsgi --ini uwsgi.ini
directory = /dir/
environment=ENVIRONMENT=STAGING
logfile-maxbytes = 300MB
stopsignal = QUIT se ha agregado porque UWSGI ignora la señal predeterminada (SIGTERM) al detenerse y muere brutalmente con SIGKILL dejando trabajadores huérfanos.
¿Hay alguna manera de que pueda investigar lo que está pasando?
EDITAR:
Intentado según lo recomendado por mnencia: /etc/init.d/supervisor stop && while /etc/init.d/supervisor status ; do sleep 1; done && /etc/init.d/supervisor start
/etc/init.d/supervisor stop && while /etc/init.d/supervisor status ; do sleep 1; done && /etc/init.d/supervisor start
/etc/init.d/supervisor stop && while /etc/init.d/supervisor status ; do sleep 1; done && /etc/init.d/supervisor start
pero aún falla la mitad del tiempo.
root@host:~# /etc/init.d/supervisor stop && while /etc/init.d/supervisor status ; do sleep 1; done && /etc/init.d/supervisor start
[ ok ] Stopping supervisor (via systemctl): supervisor.service.
● supervisor.service - LSB: Start/stop supervisor
Loaded: loaded (/etc/init.d/supervisor)
Active: inactive (dead) since Tue 2015-11-24 13:04:32 UTC; 89ms ago
Process: 23490 ExecStop=/etc/init.d/supervisor stop (code=exited, status=0/SUCCESS)
Process: 23349 ExecStart=/etc/init.d/supervisor start (code=exited, status=0/SUCCESS)
Nov 24 13:04:30 xxx supervisor[23349]: Starting supervisor: supervisord.
Nov 24 13:04:30 xxx systemd[1]: Started LSB: Start/stop supervisor.
Nov 24 13:04:32 xxx systemd[1]: Stopping LSB: Start/stop supervisor...
Nov 24 13:04:32 xxx supervisor[23490]: Stopping supervisor: supervisord.
Nov 24 13:04:32 xxx systemd[1]: Stopped LSB: Start/stop supervisor.
[....] Starting supervisor (via systemctl): supervisor.serviceJob for supervisor.service failed. See ''systemctl status supervisor.service'' and ''journalctl -xn'' for details.
failed!
root@host:~# /etc/init.d/supervisor stop && while /etc/init.d/supervisor status ; do sleep 1; done && /etc/init.d/supervisor start
[ ok ] Stopping supervisor (via systemctl): supervisor.service.
● supervisor.service - LSB: Start/stop supervisor
Loaded: loaded (/etc/init.d/supervisor)
Active: failed (Result: exit-code) since Tue 2015-11-24 13:04:32 UTC; 1s ago
Process: 23490 ExecStop=/etc/init.d/supervisor stop (code=exited, status=0/SUCCESS)
Process: 23526 ExecStart=/etc/init.d/supervisor start (code=exited, status=1/FAILURE)
Nov 24 13:04:32 xxx systemd[1]: supervisor.service: control process exited, code=exited status=1
Nov 24 13:04:32 xxx systemd[1]: Failed to start LSB: Start/stop supervisor.
Nov 24 13:04:32 xxx systemd[1]: Unit supervisor.service entered failed state.
Nov 24 13:04:32 xxx supervisor[23526]: Starting supervisor:
Nov 24 13:04:33 xxx systemd[1]: Stopped LSB: Start/stop supervisor.
[ ok ] Starting supervisor (via systemctl): supervisor.service.
Esto no es necesariamente un error del supervisor. A partir de su salida de systemctl status
que el supervisor
se inicia a través de la capa de compatibilidad sysv-init, por lo que la falla podría estar en el script /etc/init.d/supervisor
. Eso explicaría la ausencia de errores en los registros de supervisor.
Para depurar el script de inicio, la forma más sencilla es agregar un set -x
como primera instrucción sin comentarios en ese archivo, y buscar en el journalctl
salida de journalctl
el seguimiento de la ejecución del script.
EDITAR:
Lo he reproducido y depurado en un sistema de prueba con Debian Sid.
El problema es que el objetivo de detención del script de inicio del supervisor no comprueba si el daemon se ha terminado realmente, sino que solo envía una señal si el proceso existe. Si el proceso del daemon tarda un poco en cerrarse, la acción de inicio subsiguiente fallará debido al proceso del daemon moribundo, que se cuenta como ya en ejecución.
He abierto un error en Debian Bug Tracker: http://bugs.debian.org/805920
SOLUCIÓN DE TRABAJO:
Puede solucionar el problema con:
/etc/init.d/supervisor force-stop && /
/etc/init.d/supervisor stop && /
/etc/init.d/supervisor start
-
force-stop
asegurará que el supervisor se haya terminado (fuera de systemd). -
stop
asegurarte de que Systemd sepa que está terminado -
start
empieza de nuevo
La stop
después de la force-stop
forzada es obligatoria, de lo contrario, systemd ignorará cualquier solicitud de start
posterior. stop
y start
pueden combinarse usando restart
, pero aquí los puse a ambos para mostrar cómo funciona.
Tuve este problema en Ubuntu 14.04, probé el último script initd de debian y la solución @mnencia pero no funcionaron para mí. La solución de detención de la fuerza no eliminó los procesos del programa, solo se mantuvieron en funcionamiento después de que se eliminara el supervisor.
Mi solución fue parchear el supervisor y comenzar y reiniciar partes del código del script initd. No quería adivinar un buen DODTIME, quería que se activara tan pronto como el anterior proceso maestro de supervisión se extinga, así que agregué una lógica de reintento . Tenga en cuenta que es un poco detallado, pero solo puede eliminar las llamadas de eco si no le gusta ese comportamiento y puede cambiar el máximo de reties (establecido en 20 aquí).
start)
echo -n "Starting $DESC: "
i=1
until [ $i -ge 21 ]; do
start-stop-daemon --start --quiet --pidfile $PIDFILE --startas $DAEMON -- $DAEMON_OPTS && break
echo -n -e "/nAlready running, old process still finishing? retrying ($i/20)..."
let "i += 1"
sleep 1
done
sleep 1
if running ; then
echo "$NAME."
else
echo " ERROR."
fi
;;
restart)
echo -n "Restarting $DESC: "
start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE
i=1
until [ $i -ge 21 ]; do
start-stop-daemon --start --quiet --pidfile $PIDFILE --startas $DAEMON -- $DAEMON_OPTS && break
echo -n -e "/nAlready running, old process still finishing? retrying ($i/20)..."
let "i += 1"
sleep 1
done
echo "$NAME."
;;
También cambié el hashbang (primera línea), así que bash se usa en lugar de sh, quería usar let
#! /bin/bash