web-dev-qa-db-ja.com

スーパーバイザが半分の時間で再起動しない

Djangoアプリを、Debian 8.1を実行しているマシンにUwsgiとスーパーバイザーを使用してデプロイしようとしています。

Sudo systemctl restart supervisorで再起動すると、半分の時間で再起動できません。

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

ただし、supervisorまたはuwsgiログには何もありません。スーパーバイザ3.0は、uwsgiのこの構成で実行されています。

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

uWSGIは停止時にデフォルトのシグナル(SIGTERM)を無視し、孤立したワーカーを残してSIGKILLで残酷に強制終了されるため、stopsignal = QUITが追加されました。

何が起こっているのかを調査する方法はありますか?

編集:

Mnenciaがアドバイスしたように試してみました:/etc/init.d/supervisor stop && while /etc/init.d/supervisor status ; do sleep 1; done && /etc/init.d/supervisor startが、半分の時間で失敗します。

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

これは、必ずしもスーパーバイザーからのエラーではありません。 systemctl statusの出力から、supervisorがsysv-init互換性レイヤーを介して開始されていることがわかります。そのため、/etc/init.d/supervisorスクリプトにエラーがある可能性があります。監視ログにエラーがないことを説明します。

Initスクリプトをデバッグするには、set -xを最初の非コメント命令としてそのファイルに追加し、journalctl出力でスクリプト実行のトレースを確認するのが最も簡単な方法です。

編集:

Debian Sidを使用したテストシステムで再現してデバッグしました。

問題は、スーパーバイザのinitスクリプトのstopターゲットが、デーモンが実際に終了したかどうかをチェックせず、プロセスが存在する場合にのみシグナルを送信することです。デーモンプロセスのシャットダウンに時間がかかる場合、デーモンプロセスの停止が原因で、後続のstartアクションが失敗し、すでに実行されているとカウントされます。

Debianバグトラッカーでバグを公開しました: http://bugs.debian.org/80592

回避策:

次の方法で問題を回避できます。

/etc/init.d/supervisor force-stop && \
/etc/init.d/supervisor stop && \
/etc/init.d/supervisor start
  • force-stopは、supervisordが(systemdの外部で)終了したことを確認します。
  • stop終了したことをsystemdに確認してください
  • start再び開始します

force-stopの後のstopは必須です。それ以外の場合、systemdは後続のstart要求を無視します。 stopstartrestartを使用して組み合わせることができますが、ここでは両方を配置して、どのように機能するかを示します。

20
mnencia

私はubuntu 14.04でこの問題があり、debianおよび@mnenciaソリューションの最新のinitdスクリプトを試しましたが、それらは私にとってはうまくいきませんでした。 force-stopソリューションは、supervisordが強制終了された後も実行され続けたプログラムプロセスを強制終了しませんでした。

私の解決策は、スーパーバイザにパッチを当ててinitdスクリプトコードの一部を開始および再起動することでした。良いDODTIMEを推測したくなかったので、古いスーパーバイザマスタープロセスが停止するとすぐに起動し、再試行ロジックを追加しました。 。多少冗長ですが、その動作が気に入らない場合はエコー呼び出しを削除して、最大reties(ここでは20に設定)を変更できます。

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

ハッシュバング(1行目)も変更したので、bashはshの代わりに使用され、letを使用したかった

#! /bin/bash
0
gonz