Djangoアプリケーションのまれなハングをデバッグしようとしています。これまでのところ、問題を特定できませんでした。本番環境では1日に1回程度発生し、Gunicornは次のメッセージを表示してプロセスを再開します。
[CRITICAL] WORKER TIMEOUT
再起動されたプロセスのスタックトレースをダンプするようにDjangoまたはGunicornを構成する方法はありますか?
Gunicornのログをより詳細に設定してみてください。設定するINFO
かDEBUG
、ログに光を当てる可能性があります。
また、遅いリクエストをログに記録するDogSlowも確認できます。https://pypi.python.org/pypi/dogslow。
また、一般的なロギングの勝利については、Sentryを使用してみてください:https ://www.getsentry.com/welcome/ 。
ランダムな質問、その時点で実行されているサーバー上のcron、バックアップ、そのようなものはありますか?
これにより、ワーカーが強制終了されたときのスタックトレースが出力されます。gunicornの設定ファイルを作成し、その中に次の関数を貼り付ける必要があります。
def worker_abort(worker):
import traceback, io
debug_info = io.StringIO()
debug_info.write("Traceback at time of timeout:\n")
traceback.print_stack(file=debug_info)
worker.log.critical(debug_info.getvalue())
(これはPython 3でのみテストしました。Python2を使用する場合は、に変更io
する必要があります。Python3のStringIOをStringIO
参照してください) 。
タイムアウトは、要求のタイムアウトを意味するものではありません。これは、労働者の活力チェックを目的としています。同期ワーカーの場合、ワーカーはリクエストを処理する以外に何もできないため、これはリクエストタイムアウトとして機能します。非同期ワーカーは、長時間実行される要求を処理している間でもハートビートを実行するため、ワーカーがブロック/フリーズしない限り、強制終了されません。
Gunicornにはworker_abortという関数があります(以下のgunicornのドキュメントを参照)。
def worker_abort(worker):
worker.log.info("worker received abort signal")
import threading, sys, traceback
id2name = dict([(th.ident, th.name) for th in threading.enumerate()])
code = []
for threadId, stack in sys._current_frames().items():
code.append("\n# Thread: %s(%d)" % (id2name.get(threadId,""), threadId))
stack = traceback.extract_stack(stack)
for filename, lineno, name, line in stack:
code.append('File: "%s", line %d, in %s' % (filename, lineno, name))
if line:
code.append(" %s" % (line.strip()))
worker.log.debug("\n".join(code))
ワーカーがSIGABRTシグナルを受信したときに呼び出されます。この呼び出しは通常、タイムアウト時に発生します。呼び出し可能オブジェクトは、初期化されたワーカーに対して1つのインスタンス変数を受け入れる必要があります。
出典:
http://docs.gunicorn.org/en/stable/settings.html、https://github.com/benoitc/gunicorn/issues/1493、https://github.com/benoitc/gunicorn/blob/master/ _ _ _ _ examples / example_config.py