web-dev-qa-db-fra.com

Le superviseur ne redémarre pas la moitié du temps

J'essaie de déployer une application Django à l'aide d'Uwsgi et d'un superviseur sur une machine exécutant Debian 8.1.

Lorsque je redémarre via Sudo systemctl restart supervisor, il ne parvient pas à redémarrer la moitié du temps.

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

Cependant, il n'y a rien dans les journaux du superviseur ou de uwsgi . Supervisor 3.0 s'exécute avec cette configuration pour uwsgi:

[program:uwsgi]
stopsignal=QUIT
command = uwsgi --ini uwsgi.ini
directory = /dir/
environment=ENVIRONMENT=STAGING
logfile-maxbytes = 300MB

stopsignal = QUIT a été ajouté car UWSGI ignore le signal par défaut (SIGTERM) à l’arrêt et est tué brutalement lorsque SIGKILL a laissé des travailleurs orphelins.

Y a-t-il un moyen d'enquêter sur ce qui se passe?

MODIFIER:

Essayé comme mnencia conseillé: /etc/init.d/supervisor stop && while /etc/init.d/supervisor status ; do sleep 1; done && /etc/init.d/supervisor start.__, mais il échoue encore la moitié du temps.

 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.
20
Paul K.

Ce n'est pas nécessairement une erreur du superviseur. Votre sortie systemctl status indique que la variable supervisor est lancée via la couche de compatibilité sysv-init, de sorte que l'échec pourrait se produire dans le script /etc/init.d/supervisor. Cela expliquerait l’absence d’erreurs dans les journaux de supervision.

Pour déboguer le script init, le moyen le plus simple consiste à ajouter un set -x en tant que première instruction sans commentaire dans ce fichier et à regarder dans la variable journalctl le résultat de l'exécution du script.

MODIFIER:

Je l'ai reproduit et débogué sur un système de test avec Debian Sid. 

Le problème est que la cible arrêt du superviseur init-script ne vérifie pas si le démon est vraiment terminé, mais envoie uniquement un signal si le processus existe. Si le processus du démon met un certain temps à s’arrêter, l’action suivante start échouera en raison du processus de démon mourant, qui est compté comme étant déjà en cours.

J'ai ouvert un bogue sur Debian Bug Tracker: http://bugs.debian.org/805920

SOLUTION DE CONTOURNEMENT:

Vous pouvez contourner le problème avec: 

/etc/init.d/supervisor force-stop && \
/etc/init.d/supervisor stop && \
/etc/init.d/supervisor start
  • force-stop s'assurera que le superviseur est terminé (en dehors de systemd).
  • stop assurez-vous que systemd sait qu'il est terminé
  • start le redémarre

La stop après le force-stop est requise, sinon Systemd ignorera toute requête start ultérieure. stop et start peuvent être combinés en utilisant restart, mais ici, je les ai mis tous les deux pour montrer comment cela fonctionne. 

18
mnencia

J'ai eu ce problème dans Ubuntu 14.04, j'ai essayé le dernier script initd de la solution debian et @mnencia mais cela n'a pas fonctionné pour moi. La solution d'arrêt forcé n'a pas tué les processus du programme, ils ont simplement continué à fonctionner après la mort de supervisord.

Ma solution consistait à corriger le supervisord, à démarrer et à redémarrer des parties du code de script initd. Je ne voulais pas deviner un bon DODTIME, je voulais qu'il soit opérationnel dès que l'ancien processus du maître superviseur disparaît. J'ai donc ajouté une logique de nouvelle tentative. . Notez que c'est un peu bavard, mais vous pouvez simplement supprimer les appels d'écho si vous n'aimez pas ce comportement et vous pouvez modifier le nombre maximal de tentatives (défini sur 20 ici).

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."
    ;;

J'ai également changé le hashbang (première ligne) de sorte que bash est utilisé à la place de sh, je voulais utiliser let

#! /bin/bash
0
gonz