4

スーパーバイザーを使用して Python Web アプリケーションをデプロイしています。デプロイ時に、ビルドアウトによって Web アプリケーションがサーバーにインストールされ、collective.recipe.supervisor を使用してスーパーバイザーを実行するためのスクリプトが作成されます。このスクリプトは、展開プロセスの最後にファブリック スクリプトによって呼び出されます。問題は、展開スクリプトが終了すると、SIGHUP シグナルがプロセスに送信され、スーパーバイザーが再起動することです (次の行に従って: https://github.com/Supervisor/supervisor/blob/master/supervisor/supervisord .py#L300 ) ですが、何らかの理由で、Web アプリが終了した後に再起動されません。次の場合、ログ出力はありません。

2012-10-24 15:23:51,510 WARN received SIGHUP indicating restart request
2012-10-24 15:23:51,511 INFO waiting for app-server to die
2012-10-24 15:23:54,650 INFO waiting for app-server to die
2012-10-24 15:23:57,653 INFO waiting for app-server to die
2012-10-24 15:24:00,657 INFO waiting for app-server to die
2012-10-24 15:24:01,658 WARN killing 'app-server' (28981) with SIGKILL
2012-10-24 15:24:01,659 INFO stopped: app-server (terminated by SIGKILL)

そこで、質問が 2 つあります。1 つ目は、スーパーバイザーが SIGHUP で再起動する理由を知っている人はいますか? これについての説明は見つかりませんでした。また、この動作を無効にするコマンド ライン オプションもありません。2 番目の質問は、直面している問題をどのように解決できるかということです。スーパーバイザを nohup で起動しようとしましたが、SIGHUP がまだ受信されます。奇妙なことに、サーバーにログオンし、スーパーバイザーを手動で起動してログアウトすると、これは発生しません。

buildout によって生成されたスーパーバイザ スクリプトは次のとおりです。

#!/usr/bin/python2.6

import sys
sys.path[0:0] = [
'/home/username/.buildout/eggs/supervisor-3.0b1-py2.6.egg',
'/home/username/.buildout/eggs/meld3-0.6.9-py2.6.egg',
'/home/username/.buildout/eggs/distribute-0.6.30-py2.6.egg',
]


import sys; sys.argv.extend(["-c","/home/username/app_directory/parts/supervisor/supervisord.conf"])

import supervisor.supervisord

if __name__ == '__main__':
sys.exit(supervisor.supervisord.main())

また、ビルドアウトによって生成されたスーパーバイザーの構成ファイルは次のとおりです。

[supervisord]
childlogdir = /home/username/app_directory/var/log
logfile = /home/username/app_directory/var/log/supervisord.log
logfile_maxbytes = 50MB
logfile_backups = 10
loglevel = info
pidfile = /home/username/app_directory/var/supervisord.pid
umask = 022
nodaemon = false
nocleanup = false

[unix_http_server]
file = /home/username/app_directory/supervisor.sock
username = username
password = apasswd
chmod = 0700

[supervisorctl]
serverurl = unix:///home/username/app_directory/supervisor.sock
username = username
password = apasswd

[rpcinterface:supervisor]
supervisor.rpcinterface_factory=supervisor.rpcinterface:make_main_rpcinterface

[program:app-server]
command = /home/username/app_directory/bin/gunicorn --bind 0.0.0.0:5000 app:wsgi
process_name = app-server
directory = /home/username/app_directory/bin
priority = 50
redirect_stderr = false
directory = /home/username/app_directory

問題を本当に理解する前に、パッチを適用したバージョンのスーパーバイザーをインストールしたくないので、どんな情報でも大歓迎です。

前もって感謝します

4

4 に答える 4

1

このバグに遭遇した可能性があります: https://github.com/Supervisor/supervisor/issues/121

回避策は、リリースされたバージョンで修正されるまで、supervisord をダウングレードすることです。

于 2013-02-28T16:35:09.930 に答える
1

Supervisord のドキュメントには、Supervisord プロセスに SIGHUP を送信すると、「すべてのプロセスが停止し、最初に見つかった構成ファイルから構成がリロードされ、すべてのプロセスが再起動される」ことが明確に記載されています。

参照 - http://supervisord.org/running.html#signal-handlers

おそらく、プロセスが正しく動作していない可能性があります。スーパーバイザーがうまくシャットダウンしようと何度か試みたようですが、ハード キルが必要であると判断しました。

process.py:560
# kill processes which are taking too long to stop with a final
# sigkill.  if this doesn't kill it, the process will be stuck
# in the STOPPING state forever.
self.config.options.logger.warn(
    killing %r (%s) with SIGKILL' % (self.config.name, self.pid))
self.kill(signal.SIGKILL)

おそらくキルコールは失敗していますか?

于 2013-02-08T23:32:37.117 に答える
1

再起動またはリロードSIGHUPは、Linux のシステム プログラミングでは一般的な方法です。SIGHUP問題は、展開が終了した後に取得する理由です。スーパーバイザーはそれ自体を正しくデーモン化するため (起動してログアウトすると動作するため)、ボットを構築することによってリロード信号がスーパーバイザーに送信され、コードが変更されたため webapp を再起動する必要があることが示される場合があります。

そのため、新しいコードでアプリを起動するために、スーパーバイザーはアプリのシャットダウンを開始します。しかし、アプリは指定されたタイムアウトで停止せず、スーパーバイザーはアプリがハングして強制終了すると判断しSIGKILLます。

問題を解決するには、スーパーバイザーが要求したときにアプリをシャットダウンするように教える必要があります。

于 2012-10-25T13:55:04.107 に答える
0

まったく同じ問題に遭遇し、3.0a10 にダウングレードすると解決しました。

于 2013-05-21T13:48:56.933 に答える