it-swarm.com.de

Der Supervisor kann die Hälfte der Zeit nicht neu starten

Ich versuche, eine Django-App mit Uwsgi und Supervisor auf einem Computer bereitzustellen, auf dem Debian 8.1 ausgeführt wird.

Bei einem Neustart über Sudo systemctl restart supervisor wird die Hälfte der Zeit nicht neu gestartet.

$ [email protected]:/# systemctl start supervisor
    Job for supervisor.service failed. See 'systemctl status supervisor.service' and 'journalctl -xn' for details.
$ [email protected]:/# 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.

Es gibt jedoch nichts in den Supervisor- oder Uwsgi-Protokollen ..__ Supervisor 3.0 wird mit dieser Konfiguration für Uwsgi ausgeführt:

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

stopsignal = QUIT wurde hinzugefügt, da UWSGI das Standardsignal (SIGTERM) beim Stoppen ignoriert und brutal mit SIGKILL getötet wird, während Orphan-Arbeiter verlassen werden.

Gibt es eine Möglichkeit, zu untersuchen, was passiert?

BEARBEITEN:

Wie mnencia empfohlen: /etc/init.d/supervisor stop && while /etc/init.d/supervisor status ; do sleep 1; done && /etc/init.d/supervisor start Aber es scheitert immer noch die Hälfte der Zeit.

 [email protected]:~# /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!
    [email protected]:~# /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.

Dies ist nicht unbedingt ein Fehler des Vorgesetzten. Ich sehe in Ihrer systemctl status-Ausgabe, dass supervisor über die Kompatibilitätsebene sysv-init gestartet wird, sodass der Fehler möglicherweise im /etc/init.d/supervisor-Skript liegt. Dies würde das Fehlen von Fehlern in den Protokollen des Vorgesetzten erklären.

Um das Init-Skript zu debuggen, ist es am einfachsten, einen set -x als erste Anweisung ohne Kommentar in dieser Datei hinzuzufügen und die Ablaufverfolgung der Skriptausführung in der journalctl-Ausgabe anzuzeigen.

EDIT:

Ich habe es auf einem Testsystem mit Debian Sid reproduziert und debuggt. 

Das Problem ist, dass das Ziel stop des Supervisor-Init-Skripts nicht überprüft, ob der Dämon wirklich beendet wurde, sondern nur ein Signal sendet, wenn der Prozess vorhanden ist. Wenn das Herunterfahren des Daemon-Prozesses eine Weile dauert, schlägt die nachfolgende Aktion start fehl, weil der sterbende Daemon-Prozess als bereits ausgeführt gilt.

Ich habe einen Fehler in Debian Bug Tracker geöffnet: http://bugs.debian.org/805920

WORKAROUND:

Sie können das Problem mit folgenden Problemen umgehen: 

/etc/init.d/supervisor force-stop && \
/etc/init.d/supervisor stop && \
/etc/init.d/supervisor start
  • force-stop stellt sicher, dass der Supervisord beendet wurde (außerhalb von systemd).
  • stop Stelle sicher, dass systemd weiß, dass es beendet ist
  • start startet es erneut

Die stop nach dem force-stop ist erforderlich, andernfalls ignoriert systemd nachfolgende start-Anforderungen. stop und start können mit restart kombiniert werden, aber hier habe ich beide eingefügt, um zu zeigen, wie es funktioniert. 

18
mnencia

Ich hatte dieses Problem in Ubuntu 14.04, probierte das neueste initd-Skript von debian und @mnencia aus, aber es funktionierte nicht für mich. Zwangsstopp-Lösung tötete nicht die Programmprozesse, die nur ausgeführt wurden, nachdem Supervisord getötet wurde.

Meine Lösung bestand darin, das Supervisord zu patchen und Teile des initd-Skriptcodes zu starten und erneut zu starten. Ich wollte kein gutes DODTIME erraten. Ich wollte, dass es läuft, sobald der alte Supervisor-Masterprozess stirbt, und fügte eine Wiederholungslogik hinzu . Beachten Sie, dass es ein bisschen verbos ist, aber Sie können die Echoaufrufe einfach entfernen, wenn Ihnen dieses Verhalten nicht gefällt und Sie die maximalen Reties ändern können (hier auf 20 setzen).

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

Ich habe auch den Hashbang (erste Zeile) geändert, sodass bash von sh verwendet wird, ich wollte let verwenden

#! /bin/bash
0
gonz