[CRITICAL] WORKER TIMEOUT
エラーに関連するレポートがすでにいくつかあるようですが、ポップアップし続けます。 これが私の問題です。
このFlaskhelloworldアプリケーションを実行しています。
from flask import Flask
application = Flask(__name__)
@application.route('/')
def hello_world():
return 'Hello, World!'
gunicornコマンドは次のとおりです。
gunicorn -b 0.0.0.0:5000 --log-level=debug hello
そしてこれはコンソール出力です:
[2018-06-05 14:56:21 +0200] [11229] [INFO] Starting gunicorn 19.8.1
[2018-06-05 14:56:21 +0200] [11229] [DEBUG] Arbiter booted
[2018-06-05 14:56:21 +0200] [11229] [INFO] Listening at: http://0.0.0.0:5000 (11229)
[2018-06-05 14:56:21 +0200] [11229] [INFO] Using worker: sync
[2018-06-05 14:56:21 +0200] [11232] [INFO] Booting worker with pid: 11232
[2018-06-05 14:56:21 +0200] [11229] [DEBUG] 1 workers
[2018-06-05 14:56:32 +0200] [11232] [DEBUG] GET /
[2018-06-05 14:56:57 +0200] [11232] [DEBUG] Closing connection.
[2018-06-05 14:57:16 +0200] [11232] [DEBUG] GET /
[2018-06-05 14:57:47 +0200] [11229] [CRITICAL] WORKER TIMEOUT (pid:11232)
[2018-06-05 14:57:47 +0200] [11232] [INFO] Worker exiting (pid: 11232)
[2018-06-05 14:57:47 +0200] [11324] [INFO] Booting worker with pid: 11324
エラーが発生する理由と、この例で予期されているかどうかを明確に説明していただけますか? どうすれば修正できますか、それとも予想される動作である場合は、なぜ重大なエラーが発生するのでしょうか。
エラーは予期されていませんが、エラーが発生する理由を示す例はありません。 あなたの環境について詳しく教えてください。
あなたの環境について詳しく教えてください。
完全に新しいセットアップで問題を再現しました。手順は次のとおりです。
mkdir gunicorn
cd gunicorn/
pipenv --python 3.6
pipenv install flask
pipenv install gunicorn
vim hello.py
pipenv shell
gunicorn -b 0.0.0.0:5000 --log-level=debug hello
hello.py
は、最初のレポートで投稿したものとまったく同じFlaskアプリケーションです。
以下は完全なログです。
~$ gunicorn -b 0.0.0.0:5000 --log-level=debug hello
[2018-06-06 09:16:21 +0200] [19829] [DEBUG] Current configuration:
config: None
bind: ['0.0.0.0:5000']
backlog: 2048
workers: 1
worker_class: sync
threads: 1
worker_connections: 1000
max_requests: 0
max_requests_jitter: 0
timeout: 30
graceful_timeout: 30
keepalive: 2
limit_request_line: 4094
limit_request_fields: 100
limit_request_field_size: 8190
reload: False
reload_engine: auto
reload_extra_files: []
spew: False
check_config: False
preload_app: False
sendfile: None
reuse_port: False
chdir: /home/dima/work/gunicorn
daemon: False
raw_env: []
pidfile: None
worker_tmp_dir: None
user: 1000
group: 985
umask: 0
initgroups: False
tmp_upload_dir: None
secure_scheme_headers: {'X-FORWARDED-PROTOCOL': 'ssl', 'X-FORWARDED-PROTO': 'https', 'X-FORWARDED-SSL': 'on'}
forwarded_allow_ips: ['127.0.0.1']
accesslog: None
disable_redirect_access_to_syslog: False
access_log_format: %(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"
errorlog: -
loglevel: debug
capture_output: False
logger_class: gunicorn.glogging.Logger
logconfig: None
logconfig_dict: {}
syslog_addr: udp://localhost:514
syslog: False
syslog_prefix: None
syslog_facility: user
enable_stdio_inheritance: False
statsd_host: None
statsd_prefix:
proc_name: None
default_proc_name: hello
pythonpath: None
paste: None
on_starting: <function OnStarting.on_starting at 0x7f9757112d08>
on_reload: <function OnReload.on_reload at 0x7f9757112e18>
when_ready: <function WhenReady.when_ready at 0x7f9757112f28>
pre_fork: <function Prefork.pre_fork at 0x7f9756c230d0>
post_fork: <function Postfork.post_fork at 0x7f9756c231e0>
post_worker_init: <function PostWorkerInit.post_worker_init at 0x7f9756c232f0>
worker_int: <function WorkerInt.worker_int at 0x7f9756c23400>
worker_abort: <function WorkerAbort.worker_abort at 0x7f9756c23510>
pre_exec: <function PreExec.pre_exec at 0x7f9756c23620>
pre_request: <function PreRequest.pre_request at 0x7f9756c23730>
post_request: <function PostRequest.post_request at 0x7f9756c237b8>
child_exit: <function ChildExit.child_exit at 0x7f9756c238c8>
worker_exit: <function WorkerExit.worker_exit at 0x7f9756c239d8>
nworkers_changed: <function NumWorkersChanged.nworkers_changed at 0x7f9756c23ae8>
on_exit: <function OnExit.on_exit at 0x7f9756c23bf8>
proxy_protocol: False
proxy_allow_ips: ['127.0.0.1']
keyfile: None
certfile: None
ssl_version: 2
cert_reqs: 0
ca_certs: None
suppress_ragged_eofs: True
do_handshake_on_connect: False
ciphers: TLSv1
raw_paste_global_conf: []
[2018-06-06 09:16:21 +0200] [19829] [INFO] Starting gunicorn 19.8.1
[2018-06-06 09:16:21 +0200] [19829] [DEBUG] Arbiter booted
[2018-06-06 09:16:21 +0200] [19829] [INFO] Listening at: http://0.0.0.0:5000 (19829)
[2018-06-06 09:16:21 +0200] [19829] [INFO] Using worker: sync
[2018-06-06 09:16:21 +0200] [19832] [INFO] Booting worker with pid: 19832
[2018-06-06 09:16:22 +0200] [19829] [DEBUG] 1 workers
[2018-06-06 09:16:48 +0200] [19832] [DEBUG] GET /
[2018-06-06 09:17:19 +0200] [19829] [CRITICAL] WORKER TIMEOUT (pid:19832)
[2018-06-06 09:17:19 +0200] [19832] [INFO] Worker exiting (pid: 19832)
[2018-06-06 09:17:19 +0200] [19872] [INFO] Booting worker with pid: 19872
^C[2018-06-06 09:17:26 +0200] [19829] [INFO] Handling signal: int
[2018-06-06 09:17:26 +0200] [19872] [INFO] Worker exiting (pid: 19872)
[2018-06-06 09:17:26 +0200] [19829] [INFO] Shutting down: Master
~$ pip list
Package Version
------------ -------
click 6.7
Flask 1.0.2
gunicorn 19.8.1
itsdangerous 0.24
Jinja2 2.10
MarkupSafe 1.0
pip 10.0.1
setuptools 39.2.0
Werkzeug 0.14.1
wheel 0.31.1
@bigunyakデフォルトのタイムアウトが原因だと思いますが、ワーカーは30http://docs.gunicorn.org/en/stable/settings.html#timeout
ログから、
[2018-06-05 14:57:16 +0200] [11232] [DEBUG] GET /
[2018-06-05 14:57:47 +0200] [11229] [CRITICAL] WORKER TIMEOUT (pid:11232)
[2018-06-06 09:16:48 +0200] [19832] [DEBUG] GET /
[2018-06-06 09:17:19 +0200] [19829] [CRITICAL] WORKER TIMEOUT (pid:19832)
同じことがわかります。同期ワーカーを使用すると、リクエストを処理していない場合でもワーカーがタイムアウトになります。
その意味で、クリティカルレベルのログは非常に紛らわしいものです。
Geventワーカーを使用してみてください。これを解決できます。
その意味で、クリティカルレベルのログは非常に紛らわしいものです。
まさに、それが私の最初の質問でした。それが予想される動作である場合、なぜ重大なエラーが発生するのでしょうか。
ワーカーを再起動する必要がある理由についての背景を知ることもできます。おそらく、これを設計ドキュメントに追加することができます。
私もこれを見て( examples/test.py
とgunicorn test:app -b localhost:9595 --log-level=debug --timeout=5
を使用して再現)、クリティカルレベルが少し混乱していることに同意します。 デバッグレベルに変更しても大丈夫です。 @benoitc @tilgoviどう思いますか?
情報レベルはもう少し良いかもしれないと思います。
私はWin10のMSYS2でも同じことをしましたが、最終的には解決できました。
... \ gunicorn \ workers \ workertmp.pyのnotify()では、os.fchmodが元々使用されています。 ただし、MSYSでは機能しません。 os.fchmodの代わりに、os.utimeを使用しました。 コードに従います。 すべてのプラットフォームで機能すると思います。
def notify(self):
try:
self.spinner = (self.spinner + 1) % 2
os.fchmod(self._tmp.fileno(), self.spinner)
if PLATFORM.startswith('MSYS') :
os.utime(self._tmp.fileno(), None)
except AttributeError:
# python < 2.6
self._tmp.truncate(0)
os.write(self._tmp.fileno(), b"X")
@berkerpeksagリクエストが発生しないため、ワーカーが終了することは期待できません。 このエラーは、ワーカーがタイムアウトまでしばらくビジー状態になっている場合にのみ発生します。 したがって、エラーは重大です。 Imoは、ドキュメントを改善して、そのようなエラーに対するより多くのユースケースと応答を提供する必要があります。
ワーカーがビジー状態になっていないときにエラーが引き続き発生する場合は、他に何かが発生しており、おそらくバグがあります。
[編集]
私にとっても同じバグです。
python2.7のDjango1.10 / gunicorn 19.6.0 / Python 2.7.15-Debian8.8のalpineとストックカーネル3.16では、すべて正常に機能していました。
Django1.11とgunicorn19.8.1にアップデートした後、ワーカーは[CRITICAL WORKERTIMEOUT]で起動に失敗し続けます。
gunicornを19.6.0にダウングレードしても、問題は解決しません。
ホストカーネルを4.9.0に更新し(スケジュールされていました)、ワーカーはエラーなしで正常に起動しました。
しかし:
gunicorn geventを試して、アプリをオンラインに戻すことができるかどうかを確認します。
geventでgunicornを使用しても、バグは修正されませんでした。
この問題に関する更新はありますか?
@neocolorがMSYSで実際のバグを特定したよう
@bigunyakどのプラットフォームで実行していますか? 簡単な例で再現しようとしましたが、上記の手順を正確に実行することはできません。 これは、複数のフレームワークで本番環境で複数のアプリケーションを実行した私の経験と一致しています。 私の知る限り、労働者の通知システムは最近変わっていません。 私のプラットフォームはMacOS10.13.6のPython3.7ですが、Python 2.7および3.6.5のいくつかのアプリケーションの同期ワーカーを使用してGunicornを本番環境で実行し、ワーカーをブロックする正当に長いリクエストがある場合にのみワーカーのタイムアウトが表示されます。
@Tberdyの場合: --worker-tmp-dir
をtmpfsファイルシステムの外部に設定しようとするとどうなりますか? アルパインやドッカー、あるいはその組み合わせが、労働者がアービターに通知する方法を何らかの形で妨害するのではないかと思っています。
Docker関連のtmpfsの問題については、#1388も参照してください。
私はこの問題を抱えています。
私にもこの問題があります。gunicornsyncは昨夜まで完全に機能していました。レポートを開始し、geventを使用したワーカーのタイムアウト[CRITICAL]で問題が解決したようですが、なぜこれが発生したのかを知りたいと思います。
@ timoj58 @cjmashこの問題について詳しく
@benoitc kubernetesでDjangoプロジェクトを開始するためにgunicornを実行しています。gunicornの引数は、-bind = $ port --workers = 7 --timeout = 1200 --log-level = debug --access-logfile --error-logfile- 「」
ログから取得したエラー
`` `E [2018-08-09 21:47:56 +0000] [13] [INFO] pidでワーカーを起動しています:13
E [2018-08-09 21:47:56 +0000] [14] [INFO] pidを使用した起動ワーカー:14
E [2018-08-09 21:47:56 +0000] [12] [INFO] pidを使用した起動ワーカー:12
E [2018-08-09 21:47:56 +0000] [1] [DEBUG] 7人の労働者
E [2018-08-09 21:47:56 +0000] [11] [INFO] pidを使用した起動ワーカー:11
E [2018-08-09 21:47:55 +0000] [10] [INFO] pidを使用した起動ワーカー:10
E [2018-08-09 21:47:55 +0000] [9] [INFO] pidを使用した起動ワーカー:9
E [2018-08-09 21:47:55 +0000] [8] [INFO] pidを使用した起動ワーカー:8
E [2018-08-09 21:47:55 +0000] [1] [情報]ワーカーの使用:同期
E [2018-08-09 21:47:55 +0000] [1] [INFO]リスニング: http :
E [2018-08-09 21:47:55 +0000] [1] [DEBUG]アービターが起動しました
E [2018-08-09 21:47:55 +0000] [1] [INFO] gunicorn19.7.1を開始しています
E raw_paste_global_conf:[]
E暗号:TLSv1
E do_handshake_on_connect:False
Esuppress_ragged_eofs:True
E ca_certs:なし
E cert_reqs:0
E ssl_version:2
E certfile:なし
Eキーファイル:なし
E proxy_allow_ips:['127.0.0.1']
E proxy_protocol:False
E on_exit:
E nworkers_changed:
E worker_exit:
E child_exit:
E post_request:
E pre_request:
E pre_exec:
E worker_abort:
E worker_int:
E post_worker_init:
E post_fork:
E pre_fork:
E when_ready:
E on_reload:
E on_starting:
Eペースト:なし
E pythonpath:なし
E default_proc_name:art.wsgi
E proc_name:なし
E statsd_prefix:
E statsd_host:なし
E enable_stdio_inheritance:False
E syslog_facility:user
E syslog_prefix:なし
E syslog:False
E syslog_addr: udp:// localhost :514
E logconfig:なし
E logger_class:gunicorn.glogging.Logger
E Capture_output:False
Eログレベル:デバッグ
Eエラーログ:-
E access_log_format:%(h)s%(l)s%(u)s%(t)s "%(r)s"%(s)s%(b)s "%(f)s" "%(なので"
Eアクセスログ:-
E forwarded_allow_ips:['127.0.0.1']
E secure_scheme_headers:{'X-FORWARDED-PROTOCOL': 'ssl'、 'X-FORWARDED-PROTO': 'https'、 'X-FORWARDED-SSL': 'on'}
E tmp_upload_dir:なし
E initgroups:False
E umask:0
Eグループ:0
Eユーザー:0
E worker_tmp_dir:なし
E pidfile:なし
E raw_env:[]
Eデーモン:False
E chdir:/ usr / src / app
E sendfile:なし
E preload_app:False
E check_config:False
E spew:False
E reload_engine:auto
Eリロード:False
E limit_request_field_size:8190
E limit_request_fields:100
E limit_request_line:4094
Eキープアライブ:2
E graceful_timeout:30
Eタイムアウト:1200
E max_requests_jitter:0
E max_requests:0
E worker_connections:1000
Eスレッド:1
E worker_class:同期
E労働者:7
Eバックログ:2048
Eバインド:['0.0.0.0:4040']
E構成:なし
E [2018-08-09 21:47:55 +0000] [1] [DEBUG]現在の構成:
適用する移行はありません。
移行を実行しています:
すべての移行を適用します:admin、auth、contenttypes、core、dashboard、jet、oauth2_provider、sessions
I実行する操作:
E [2018-08-09 21:47:20 +0000] [13] [INFO]ワーカーが終了します(pid:13)
E os.path.dirname(os.path.dirname(__ file __))、 '。env'))
E /usr/src/app/art/wsgi.py:19:UserWarning:/usr/src/app/.envを読み取っていません-存在しません。
E [2018-08-09 21:47:00 +0000] [21] [INFO] pidを使用した起動ワーカー:21
E [2018-08-09 21:47:00 +0000] [1] [INFO]処理信号:用語
E [2018-08-09 21:46:35 +0000] [12] [INFO] pidを使用した起動ワーカー:12
E [2018-08-09 21:46:34 +0000] [13] [INFO] pidを使用した起動ワーカー:13
E [2018-08-09 21:46:34 +0000] [11] [INFO] pidを使用した起動ワーカー:11
E [2018-08-09 21:46:34 +0000] [1] [DEBUG] 7人の労働者
E [2018-08-09 21:46:34 +0000] [10] [INFO] pidを使用した起動ワーカー:10
E [2018-08-09 21:46:34 +0000] [9] [INFO] pidを使用した起動ワーカー:9
E [2018-08-09 21:46:34 +0000] [8] [INFO] pidを使用した起動ワーカー:8
E [2018-08-09 21:46:34 +0000] [7] [INFO] pidを使用した起動ワーカー:7
E [2018-08-09 21:46:34 +0000] [1] [情報]ワーカーの使用:同期
E [2018-08-09 21:46:34 +0000] [1] [INFO]リスニング: http :
E [2018-08-09 21:46:34 +0000] [1] [DEBUG]アービターが起動しました
E [2018-08-09 21:46:34 +0000] [1] [INFO] gunicorn19.7.1を開始しています
E raw_paste_global_conf:[]
E暗号:TLSv1
E do_handshake_on_connect:False
Esuppress_ragged_eofs:True
E ca_certs:なし
E cert_reqs:0
E ssl_version:2
E certfile:なし
Eキーファイル:なし
E proxy_allow_ips:['127.0.0.1']
E proxy_protocol:False
E on_exit:
E nworkers_changed:
E worker_exit:
E child_exit:
E post_request:
E pre_request:
E pre_exec:
E worker_abort:
E worker_int:
E post_worker_init:
E post_fork:
E pre_fork:
E when_ready:
E on_reload:
E on_starting:
Eペースト:なし
E pythonpath:なし
E default_proc_name:art.wsgi
E proc_name:なし
E statsd_prefix:
E statsd_host:なし
E enable_stdio_inheritance:False
E syslog_facility:user
E syslog_prefix:なし
E syslog:False
E syslog_addr: udp:// localhost :514
E logconfig:なし
E logger_class:gunicorn.glogging.Logger
E Capture_output:False
Eログレベル:デバッグ
Eエラーログ:-
E access_log_format:%(h)s%(l)s%(u)s%(t)s "%(r)s"%(s)s%(b)s "%(f)s" "%(なので"
Eアクセスログ:-
E forwarded_allow_ips:['127.0.0.1']
E secure_scheme_headers:{'X-FORWARDED-PROTOCOL': 'ssl'、 'X-FORWARDED-PROTO': 'https'、 'X-FORWARDED-SSL': 'on'}
E tmp_upload_dir:なし
E initgroups:False
E umask:0
Eグループ:0
Eユーザー:0
E worker_tmp_dir:なし
E pidfile:なし
E raw_env:[]
Eデーモン:False
E chdir:/ usr / src / app
E sendfile:なし
E preload_app:False
E check_config:False
E spew:False
E reload_engine:auto
Eリロード:False
E limit_request_field_size:8190
E limit_request_fields:100
E limit_request_line:4094
Eキープアライブ:2
E graceful_timeout:30
Eタイムアウト:1200
E max_requests_jitter:0
E max_requests:0
E worker_connections:1000
Eスレッド:1
E worker_class:同期
E労働者:7
Eバックログ:2048
Eバインド:['0.0.0.0:4040']
E構成:なし
E [2018-08-09 21:46:34 +0000] [1] [DEBUG]現在の構成:
`` `
今回は問題を再現するのに少し苦労しましたが、最新のgunicornバージョン19.9.0にはまだ残っています。
それを再現する手順は、この投稿で説明したものとまったく同じです。
私のシステムはArchLinux x86_64 GNU / Linux(カーネル4.17.2-1-ARCH)、Python3.6.5です。
これが新しいログトレースです。
~$ gunicorn -b 0.0.0.0:5000 --log-level=debug hello
[2018-08-10 09:48:40 +0200] [23114] [DEBUG] Current configuration:
config: None
bind: ['0.0.0.0:5000']
backlog: 2048
workers: 1
worker_class: sync
threads: 1
worker_connections: 1000
max_requests: 0
max_requests_jitter: 0
timeout: 30
graceful_timeout: 30
keepalive: 2
limit_request_line: 4094
limit_request_fields: 100
limit_request_field_size: 8190
reload: False
reload_engine: auto
reload_extra_files: []
spew: False
check_config: False
preload_app: False
sendfile: None
reuse_port: False
chdir: /home/dima/lerning/python/modules/gunicorn
daemon: False
raw_env: []
pidfile: None
worker_tmp_dir: None
user: 1000
group: 985
umask: 0
initgroups: False
tmp_upload_dir: None
secure_scheme_headers: {'X-FORWARDED-PROTOCOL': 'ssl', 'X-FORWARDED-PROTO': 'https', 'X-FORWARDED-SSL': 'on'}
forwarded_allow_ips: ['127.0.0.1']
accesslog: None
disable_redirect_access_to_syslog: False
access_log_format: %(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"
errorlog: -
loglevel: debug
capture_output: False
logger_class: gunicorn.glogging.Logger
logconfig: None
logconfig_dict: {}
syslog_addr: udp://localhost:514
syslog: False
syslog_prefix: None
syslog_facility: user
enable_stdio_inheritance: False
statsd_host: None
statsd_prefix:
proc_name: None
default_proc_name: hello
pythonpath: None
paste: None
on_starting: <function OnStarting.on_starting at 0x7f5f8b9dad08>
on_reload: <function OnReload.on_reload at 0x7f5f8b9dae18>
when_ready: <function WhenReady.when_ready at 0x7f5f8b9daf28>
pre_fork: <function Prefork.pre_fork at 0x7f5f8b4ec0d0>
post_fork: <function Postfork.post_fork at 0x7f5f8b4ec1e0>
post_worker_init: <function PostWorkerInit.post_worker_init at 0x7f5f8b4ec2f0>
worker_int: <function WorkerInt.worker_int at 0x7f5f8b4ec400>
worker_abort: <function WorkerAbort.worker_abort at 0x7f5f8b4ec510>
pre_exec: <function PreExec.pre_exec at 0x7f5f8b4ec620>
pre_request: <function PreRequest.pre_request at 0x7f5f8b4ec730>
post_request: <function PostRequest.post_request at 0x7f5f8b4ec7b8>
child_exit: <function ChildExit.child_exit at 0x7f5f8b4ec8c8>
worker_exit: <function WorkerExit.worker_exit at 0x7f5f8b4ec9d8>
nworkers_changed: <function NumWorkersChanged.nworkers_changed at 0x7f5f8b4ecae8>
on_exit: <function OnExit.on_exit at 0x7f5f8b4ecbf8>
proxy_protocol: False
proxy_allow_ips: ['127.0.0.1']
keyfile: None
certfile: None
ssl_version: 2
cert_reqs: 0
ca_certs: None
suppress_ragged_eofs: True
do_handshake_on_connect: False
ciphers: TLSv1
raw_paste_global_conf: []
[2018-08-10 09:48:40 +0200] [23114] [INFO] Starting gunicorn 19.9.0
[2018-08-10 09:48:40 +0200] [23114] [DEBUG] Arbiter booted
[2018-08-10 09:48:40 +0200] [23114] [INFO] Listening at: http://0.0.0.0:5000 (23114)
[2018-08-10 09:48:40 +0200] [23114] [INFO] Using worker: sync
[2018-08-10 09:48:40 +0200] [23117] [INFO] Booting worker with pid: 23117
[2018-08-10 09:48:40 +0200] [23114] [DEBUG] 1 workers
[2018-08-10 09:48:45 +0200] [23117] [DEBUG] GET /
[2018-08-10 09:48:54 +0200] [23117] [DEBUG] GET /
[2018-08-10 09:49:00 +0200] [23117] [DEBUG] GET /
[2018-08-10 09:49:18 +0200] [23117] [DEBUG] Closing connection.
[2018-08-10 09:49:18 +0200] [23117] [DEBUG] GET /
[2018-08-10 09:49:23 +0200] [23117] [DEBUG] GET /
[2018-08-10 09:49:37 +0200] [23117] [DEBUG] Closing connection.
[2018-08-10 09:49:37 +0200] [23117] [DEBUG] GET /
[2018-08-10 09:49:50 +0200] [23117] [DEBUG] Closing connection.
[2018-08-10 09:51:11 +0200] [23117] [DEBUG] GET /
[2018-08-10 09:51:13 +0200] [23117] [DEBUG] GET /
[2018-08-10 09:51:43 +0200] [23114] [CRITICAL] WORKER TIMEOUT (pid:23117)
[2018-08-10 09:51:43 +0200] [23117] [INFO] Worker exiting (pid: 23117)
[2018-08-10 09:51:44 +0200] [23229] [INFO] Booting worker with pid: 23229
以前と同じように、Chromiumでhttp://0.0.0.0:5000/をヒットしていました。
以下は、正確な環境を確認するためのPipfileおよびPipfile.lockの内容です。
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
flask = "*"
gunicorn = "*"
[dev-packages]
[requires]
python_version = "3.6"
{
"_meta": {
"hash": {
"sha256": "81cb5d5f0b11719d8d9c5ec9cc683fdcf959c652fda256d5552a82d0f459a99c"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3.6"
},
"sources": [
{
"name": "pypi",
"url": "https://pypi.org/simple",
"verify_ssl": true
}
]
},
"default": {
"click": {
"hashes": [
"sha256:29f99fc6125fbc931b758dc053b3114e55c77a6e4c6c3a2674a2dc986016381d",
"sha256:f15516df478d5a56180fbf80e68f206010e6d160fc39fa508b65e035fd75130b"
],
"version": "==6.7"
},
"flask": {
"hashes": [
"sha256:2271c0070dbcb5275fad4a82e29f23ab92682dc45f9dfbc22c02ba9b9322ce48",
"sha256:a080b744b7e345ccfcbc77954861cb05b3c63786e93f2b3875e0913d44b43f05"
],
"index": "pypi",
"version": "==1.0.2"
},
"gunicorn": {
"hashes": [
"sha256:aa8e0b40b4157b36a5df5e599f45c9c76d6af43845ba3b3b0efe2c70473c2471",
"sha256:fa2662097c66f920f53f70621c6c58ca4a3c4d3434205e608e121b5b3b71f4f3"
],
"index": "pypi",
"version": "==19.9.0"
},
"itsdangerous": {
"hashes": [
"sha256:cbb3fcf8d3e33df861709ecaf89d9e6629cff0a217bc2848f1b41cd30d360519"
],
"version": "==0.24"
},
"jinja2": {
"hashes": [
"sha256:74c935a1b8bb9a3947c50a54766a969d4846290e1e788ea44c1392163723c3bd",
"sha256:f84be1bb0040caca4cea721fcbbbbd61f9be9464ca236387158b0feea01914a4"
],
"version": "==2.10"
},
"markupsafe": {
"hashes": [
"sha256:a6be69091dac236ea9c6bc7d012beab42010fa914c459791d627dad4910eb665"
],
"version": "==1.0"
},
"werkzeug": {
"hashes": [
"sha256:c3fd7a7d41976d9f44db327260e263132466836cef6f91512889ed60ad26557c",
"sha256:d5da73735293558eb1651ee2fddc4d0dedcfa06538b8813a2e20011583c9e49b"
],
"version": "==0.14.1"
}
},
"develop": {}
}
参考までに、私はこの失敗を非常に定期的に見ています:
nohup gunicorn -w 8 --access-logfile =-bind 127.0.0.1:5000 wsgi&
私はただwsgi.pyを持っています
from chart_api import application
if __name__ == "__main__":
application.run()
私に試してもらいたい/実験してほしいことがあるかどうか、またはログに確認してほしい詳細があるかどうかを知らせてください。 GCPVMでflaskを実行しています。
返事が遅れて申し訳ありません。 私はそれを実行しています
gunicorn --log-file = / home / ubuntu / log / gunicorn.logpredictor_api :app -b localhost:5000 &
gevent設定などを使用しましたが、問題を回避するために必要なものの設計を変更したため、上記の基本設定(これも失敗しましたが、geventがない場合は予想されます)
Pythonバージョン3.6
env:aws tensorflow_p36 optmized(ubuntu)
nginxは、フラスコアプリを実行しているgunicornの前に座っています。
フラスコバージョン1.0.2
nginxバージョン1.10.3
gunicornバージョン19.9.0
これが原因である可能性がある場合に備えて、nginxタイムアウトも変更しました。
gunicornサーバーで同じ問題に直面している
#gunicornアプリケーションionServer:app -b 0.0.0.0:6001 -w 8 --threads 4 --backlog 2048 \
#-timeout 120 --graceful-timeout 60 --access-logfile logs / access.log \
フラスコ== 0.12.1
gunicorn == 19.7.1
上記のコマンドでサーバーを起動すると、システムがしばらくフリーズし、ワーカーpidが起動し続けますが、タイムアウトを120秒保持し、サーバーは単一の要求を受け入れていません。
この問題に関する更新はありますか? 私は同じ問題を抱えています
[重要]ワーカータイムアウト
誰かがDockerイメージでこれをうまく再現したかどうか疑問に思っていますか?
また、gunicorn -k gevent --threads4で始まる既存のアプリケーションにdatadogのddtrace-runワーカーを実装しようとしたときにもこれが表示されます。
私も今まで見たことがないSystemExitの面白い痕跡...
[2018-11-07 11:11:50 +0000] [15987] [INFO] Booting worker with pid: 15987
[2018-11-07 11:11:50 +0000] [15977] [DEBUG] 1 workers
[2018-11-07 11:12:20 +0000] [15977] [CRITICAL] WORKER TIMEOUT (pid:15987)
Exception SystemExit: 1 in <bound method LibevLoop._loop_will_run of <cassandra.io.libevreactor.LibevLoop object at 0x7f3cb66d4a50>> ignored
ワーカー数とスレッド数を一致させることで、この問題を解決できます。
workers = (2 * cpu_count) + 1
を設定しましたが、スレッドは設定しませんでした。
threads = workers
を変更すると、すべてが正常に機能し始めました。 念のため、これが誰かを助けるなら。
これが今の様子です
def run(host='0.0.0.0', port=8080, workers=1 + (multiprocessing.cpu_count() * 2)):
"""Run the app with Gunicorn."""
if app.debug:
app.run(host, int(port), use_reloader=False)
else:
gunicorn = WSGIApplication()
gunicorn.load_wsgiapp = lambda: app
gunicorn.cfg.set('bind', '%s:%s' % (host, port))
gunicorn.cfg.set('workers', workers)
gunicorn.cfg.set('threads', workers)
gunicorn.cfg.set('pidfile', None)
gunicorn.cfg.set('worker_class', 'sync')
gunicorn.cfg.set('keepalive', 10)
gunicorn.cfg.set('accesslog', '-')
gunicorn.cfg.set('errorlog', '-')
gunicorn.cfg.set('reload', True)
gunicorn.chdir()
gunicorn.run()
AWS ElasticBeanstalkで単一のDockerコンテナを使用してDjangoを実行するとこの問題が発生しました。 セキュリティグループを修正して、EC2インスタンスがRDSインスタンスと通信できるようにすることで、この問題を解決しました。 これはこの問題に関する99%の人々の解決策ではないかもしれないことを認識していますが、他の人がこのウサギの穴に落ちる時間を無駄にしないように、このメモを残しています。
私の場合、問題はsystemctl daemon-reload
実行することで解決されました。
簡単に言うと、デフォルトのタイムアウトが30秒であることは知っていましたが、サービスに変更を適用するには、もちろんsystemdデーモンをリロードする必要があると判断するまで変更できませんでした。
@bigunyak @benoitc @tilgovi
長いグーグルガチョウの追跡といくつかの実験の後、この問題の根本的な原因は、Chromeの「事前接続/予測サービス」(ChromeとChromiumの両方でデフォルトで有効になっている)であると思います。
@jeitingはこの問題について素晴らしい記事を書きました
https://hackernoon.com/chrome-preconnect-breaks-singly-threaded-servers-95944be16400
いくつかの追加の読書:
https://github.com/corydolphin/flask-cors/issues/147
https://github.com/pallets/flask/issues/2169
TLDR
場合によっては、Chrome / Chromiumが開いて「空の」TCP接続を保持します(つまり、すぐに別のリソースをフェッチすることを予測します)。 「空の」TCP接続が最初にgunicornサーバーに到達した場合、「空の」リクエストを処理するワーカーがタイムアウトするまで、Chromeからの後続の「実際の」リクエストは「空の」リクエストの背後でスタックする可能性があります。 これは、gunicornで単一の同期ワーカーのみを実行している場合に発生する可能性が高くなります。 しかし、私の実験でわかったように、複数の同期ワーカーを実行している場合でも発生する可能性があります。
私の環境
FROM ubuntu:18.04
...
RUN pip3 install Flask==1.0.2
RUN pip3 install gunicorn==19.9.0
RUN pip3 install flask-cors==3.0.6
......
実験1
Gunicornの設定:1つの同期ワーカー(デフォルトは30秒のタイムアウト)
Firefox:ほぼすべてのreactページの読み込みで、CORS OPTIONSリクエストは5秒間ブロックされ、その後成功します。
Chromium:すべての反応ページの読み込み時に、CORSOPTIONSリクエストは1.5分間ブロックされます!!!! そして成功します。
Chromium(予測サービスが無効):すべてが正常に読み込まれます
Chrome:すべてが正常に読み込まれます
実験2
Gunicornの設定:4つの同期ワーカー(デフォルトは30秒のタイムアウト)
Firefox:すべてが正常に読み込まれます
Chromium:3回目のreactページの読み込みごとに、CORS OPTIONSリクエストは30秒間ブロックされ、その後成功します。
Chromium(予測サービスが無効):すべてが正常に読み込まれます
Chrome:すべてが正常に読み込まれます
実験3
Gunicornの設定:8つの同期ワーカー(デフォルトは30秒のタイムアウト)
Firefox:すべてが正常に読み込まれます
クロム:すべてが正常にロードされます
Chrome:すべてが正常に読み込まれます
実験4
threaded=True
flask開発サーバーを実行します
Firefox:すべてが正常に読み込まれます
クロム:すべてが正常にロードされます
Chrome:すべてが正常に読み込まれます
実験のまとめ
解決
本番環境で:最も簡単な修正は、nginxをgunicornの前に配置することです。 nginxがこの問題を解決する理由を理解したい場合は、それを説明する素晴らしい記事があります: https :
開発中:最も簡単な修正は、 threaded=True
flask開発サーバーを実行することです。 または、Chrome / Chromiumで予測サービスを無効にすることもできます。
gunicornのデバッグの改善
将来このような問題をデバッグするために、同期ワーカーのselect()
およびaccept()
呼び出しの横にデバッグログステートメントを追加することをお勧めします。
https://github.com/benoitc/gunicorn/blob/e974f30517261b2bc95cfb2017a8688f367c8bf3/gunicorn/workers/sync.py#L26
https://github.com/benoitc/gunicorn/blob/e974f30517261b2bc95cfb2017a8688f367c8bf3/gunicorn/workers/sync.py#L34
これは、ワーカーが新しいTCP接続を受け入れたが、データを受信していないことを示します。
@asnisarenkoスーパーライトアップ、ありがとう。 #1929は、シングルスレッドサーバーで同様の症状を引き起こす低速クライアントのもう1つの珍しいケースです。この場合、非TLSポートへのTLSハンドシェイクは、適切なヘッダーをすばやく送信できないため、低速書き込みクライアントのように見えます。 。
シングルスレッドの同期ワーカーは、妥当な時間内にすべてではないにしても、少なくとも最初のリクエストヘッダー行を送信できないクライアントのために、新しい調整可能な積極的なクライアントドロップを必要とするため、Gunicornの可能性があります。
これがアプリで発生した場合は、一時的な診断コードを追加できます。
def trace_on_abort():
import signal
import traceback
def print_trace(sig, frame):
print(''.join(traceback.format_stack(frame)))
signal.signal(signal.SIGABRT, print_trace)
うまくいけば、これはあなたのアプリがどこにぶら下がっているのかを明らかにするはずです。
たとえば、私はどういうわけかgevent.monkey.patch_all()
import flask
前にapp._before_request_lock
は最終的に非イベントロックになりました(つまり、パッチが適用されていないthreading.Lock
)。 このような場合、アプリの起動時に2つのリクエストが連続して発生すると、アプリがハングします(2番目のリクエストはスレッド全体をロックします)。 しかし、これは私のバグであり、あなたのバグは異なる場合があります。
@asnisarenkoなぜハングアップしているのかread()
が送信されると、グリーンレットをブロックすることを意味しますが、 read
はモンキーパッチを適用する必要があるため、他のグリーンレット。
@ikonst
この問題は、デフォルト設定でgunicornを実行することについて話している。 デフォルトのワーカークラスはsync
http://docs.gunicorn.org/en/stable/settings.html#worker -class
sync
ワーカーはプリフォークモデルを使用し、各ワーカーは一度に1つのTCP接続/要求を処理します。
何が原因かわかりませんが、デフォルトのsync
ワーカータイプからeventlet
切り替えると、問題が解決しました。
CMD pipenv run gunicorn webapp -b 0.0.0.0:8080 -k eventlet
幸運を。
たぶんこれは私だけに役立つでしょうが、私の側でこの問題をデバッグするのに7時間かかったので(EC2のDockerで実行されているFlask / Gunicornアプリ)、この頭痛の種を数人に免れることができれば、それは小さな勝利です。
コンテナのメモリ制限が低すぎました。
将来メモリリークが発生した場合は、より高いメモリ制限を設定しようとしますが、現時点では制限はありません。
ありがとう
def trace_on_abort(): import signal import traceback def print_trace(sig, frame): print(''.join(traceback.format_stack(frame))) signal.signal(signal.SIGABRT, print_trace)
あなたは私を大いに助けてくれます。 EHU)))
このtrace_on_abort()
メソッドはどこに行きますか? アプリのコードファイルで? 注釈が必要ですか?
@ mattg-vbtデバッグが必要な場合はこれをアプリの先頭に追加し、デバッグが完了したら削除します
@ikonstこれをアプリに追加しましたが、ヒットすることはありません。 ワーカータイムアウトが発生しますが、このメソッドはヒットしません。
@ mattg-vbt kill -ABRT $pid
を実行して、 print_trace
関数が呼び出されていることを確認できますか? (アイデアは、ワーカーがタイムアウトしたときにwerkzeugからSIGABRTを取得するというものですが、最初に、それが呼び出されていることを確認しましょう)
@asnisarenkoは、私たちの間であまり知識がない
web gunicorn app:app -k gevent --worker-connections 1000
?
@SumNeuron
(同期ワーカーの代わりに)geventワーカーを使用している場合は、この問題が発生することはありません。 したがって、投稿したコマンドは問題ないようです。
この問題は、初期化時にのみgeventワーカーで発生します。これは、アプリを起動する前にいくつかのタスクを処理しているため、少し面倒です。 しかし、私は今のところ高いタイムアウトを設定しています。
再現可能なテストリポジトリをここに投稿しました:https://github.com/zamponotiropita/test-gunicorn-worker-timeout-> test_0が失敗し、test_1とtest_2が合格
@zamponotiropitaフォークする前に、このワーカーごとまたはアプリごとに実行しようとしていますか?
@ikonst実行ファイルrun.sh
を確認してください。これはワーカーごとです。 問題はプリロードでは発生しませんでしたが、プリロード時にデータベースに接続する際に問題が発生しました。これは、アプリオブジェクト(およびデータベース接続と一緒に)がフォーク時にコピーされてプロセスに渡されるためです->データベースで処理できませんでしたマスターとワーカーの接続が同じで、回避策が見つかりませんでした
同様の問題が発生しています。 Flaskを使用してオンザフライで大量のデータを生成しようとしています
このメソッドでは、 --timeout
に設定されているものが期限切れになるとワーカーがタイムアウトするため、失敗します。 再現するための最小限の例:
test_gunicorn_timeout.py
import flask
from time import sleep
app = flask.Flask(__name__)
@app.route('/')
def gunicorn_timeout():
def generator():
for _ in range(10):
yield b'Yet another line...'
sleep(2)
return flask.Response(generator(), mimetype='text/plain')
次に、 gunicorn --timeout 10 test_gunicorn_timeout:app
を実行し、10秒後にlocalhost:8000
をリクエストすると、
[CRITICAL] WORKER TIMEOUT
。
また、 -k gevent
と-k eventlet
、何も変わりませんでした。
私はWindows10Proを使用しています。 DockerComposeを使用gunicorn app -b 0.0.0.0:8000 -k gevent
私のPythonコンテナにgeventをインストールすることで私のために働いた
geventのインストール方法
次に、
gunicorn --timeout 10 test_gunicorn_timeout:app
を実行し、10秒後にlocalhost:8000
をリクエストすると、
[CRITICAL] WORKER TIMEOUT
。また、
-k gevent
と-k eventlet
、何も変わりませんでした。
@ltskv
[CRITICAL] WORKER TIMEOUTの問題の解決策を見つけましたか?
heroku(gunicornを使用)にデプロイしようとしているフラスコストリーミングエンドポイントでも同様の問題が発生します。 そこでは、プロキシフロントエンドは、一部のデータが30秒以内に送信される限り接続を維持することになっていますが、gunicornは、まだ実行されてデータを生成しているにもかかわらず、30秒以内に終了しなかった場合、プロセスを強制終了するようです。
この点に関して、gunicornのドキュメントは私にははっきりとわかりません。 --timeoutの場合、 Workers silent for more than this many seconds are killed and restarted.
と表示されますが、データを生成しているにもかかわらず、30秒後にワーカーが殺されたようです。
この点に関して、gunicornのドキュメントは私にははっきりとわかりません。 --timeoutの場合、この秒数を超えてサイレントなワーカーが強制終了され、再起動されます。 しかし、彼らはまだデータを生成しているにもかかわらず、労働者は30秒後に殺されているようですか?
@ kurt-ドキュメントを改善する必要があるというhectic。 サイレントとは、一時ファイルを介してワーカーと通信するアービタープロセスの観点からサイレントを意味します。 ワーカーがデータの送信でビジー状態の場合、そのファイルは更新されません。 アービターの観点からは、ワーカーはハートビートを失っています。
#1974も参照してください。
デフォルト以外のワーカーを使用すると、同期ワーカーは大きなボディのストリーミングに関する問題を軽減する必要があります。これは、他のワーカーがリクエストを処理している場合でも一時ファイルをハートビートするためです。
@ kurt-hectic -k gevent
オプションをもう一度チェックし、ジェネレーターの反復の間にsleep(0)
を挿入しましたが、実際に機能しました(その時点で機能しなかった理由はわかりません)。私は質問を投稿しました)。
--timeout = 5
これがこの問題の最も一般的な原因です。
私の解決策があなたのお役に立てば幸いです。 私は数日前にこの重大なワーカータイムアウトの問題に遭遇し、いくつかの解決策を試しました。 今ではうまく機能します。
これが私の理解と解決策です:
サービスを開始するためにテンソルフローバックエンドなどのパッケージをロードするためにより多くの時間が必要なため、ワーカーの起動に失敗します。 そのため、アプリの起動時間が遅い場合は、gunicornでプリロードオプションを有効にしてみてください(https://devcenter.heroku.com/articles/python-gunicorn#advanced-configurationを参照)。
gunicorn hello:app --preload
デフォルトのタイムアウトは30秒です。 アプリケーションがAPIを完了するのに本当に多くの時間を必要とする場合は、タイムアウトを増やしてください。
gunicorn hello:app --timeout 10
ただし、私の観点からは、APIが終了するのに1分以上かかる場合は意味がありません。 もしそうなら、あなたのコードでいくらかの進歩を遂げるようにしてください。
今日も同じ問題に直面しました。 私の場合、APIがデータを計算してクライアントに戻るのに約1分かかっていたため、CRITICAL WORKERTIMEOUTエラーが発生しました。 gunicornのタイムアウトフラグを1分以上に増やすことで解決しました。問題は解決しましたが、問題が再発することはありませんでした。 お役に立てれば。 私はuvicorn.workers.UvicornWorkerを使用しています。
gnuicornにワーカーを追加して、これを修正しました。
web: gunicorn --workers=3 BlocAPI:app --log-file -
理由はわかりません。
多分あなたは行き詰まりを持っていましたか? アプリはそれ自体にリクエストを送信しますか?
2020年1月5日、日曜日、10:52 alpinechicken、 notifications @ github.comは次のように書いています。
gnuicornにワーカーを追加して、これを修正しました。
web:gunicorn --workers = 3 BlocAPI:app -- file-
理由はわかりません。
—
コメントしたのでこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/benoitc/gunicorn/issues/1801?email_source=notifications&email_token=AAAEQJVQRCW3C63EZJWIN5DQ4G3WTA5CNFSM4FDLD5PKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN
または購読を解除する
https://github.com/notifications/unsubscribe-auth/AAAEQJXZM4NLK56DZMFSZALQ4G3WTANCNFSM4FDLD5PA
。
うん、あるルートが別のルートを呼び出す-それは悪いですか?
これは、少なくとも2人のワーカーが必要であることを意味します。そうでない場合、サーバーは
デッドロック。 リクエストは、サーバーが2番目に応答するまで待機します
リクエスト(キューに入れられます)。
ワーカーごとに1つの同時リクエストを受け取ります。
2020年1月6日月曜日、02:45 alpinechicken、 notifications @ github.comは次のように書いています。
うん、あるルートが別のルートを呼び出す-それは悪いですか?
—
コメントしたのでこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/benoitc/gunicorn/issues/1801?email_source=notifications&email_token=AAAEQJSFEFBBI6AMZJCM4C3Q4KLOJA5CNFSM4FDLD5PKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW
または購読を解除する
https://github.com/notifications/unsubscribe-auth/AAAEQJXTCPOFIZJU5PUPOODQ4KLOJANCNFSM4FDLD5PA
。
ああ、それは理にかなっています。 ありがとう!
火、2020年1月7日には6:23でbobf [email protected]書きました:
これは、少なくとも2人のワーカーが必要であることを意味します。そうでない場合、サーバーは
デッドロック。 リクエストは、サーバーが2番目に応答するまで待機します
リクエスト(キューに入れられます)。ワーカーごとに1つの同時リクエストを受け取ります。
2020年1月6日月曜日、02:45 alpinechicken、 notifications @ github.comは次のように書いています。
うん、あるルートが別のルートを呼び出す-それは悪いですか?
—
コメントしたのでこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
<<
https://github.com/benoitc/gunicorn/issues/1801?email_source=notifications&email_token=AAAEQJSFEFBBI6AMZJCM4C3Q4KLOJA5CNFSM4FDLD5PKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW
、
または購読を解除する
<<
https://github.com/notifications/unsubscribe-auth/AAAEQJXTCPOFIZJU5PUPOODQ4KLOJANCNFSM4FDLD5PA。
—
コメントしたのでこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/benoitc/gunicorn/issues/1801?email_source=notifications&email_token=AAH2WRPVPVO2EJ53BKQW5B3Q4OHLRA5CNFSM4FDLD5PKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW
または購読を解除する
https://github.com/notifications/unsubscribe-auth/AAH2WRM2LLIB4O6OHCU5UG3Q4OHLRANCNFSM4FDLD5PA
。
worker_class '、' sync ')
ワーカー数とスレッド数を一致させることで、この問題を解決できます。
workers = (2 * cpu_count) + 1
を設定しましたが、スレッドは設定しませんでした。
threads = workers
を変更すると、すべてが正常に機能し始めました。 念のため、これが誰かを助けるなら。これが今の様子です
def run(host='0.0.0.0', port=8080, workers=1 + (multiprocessing.cpu_count() * 2)): """Run the app with Gunicorn.""" if app.debug: app.run(host, int(port), use_reloader=False) else: gunicorn = WSGIApplication() gunicorn.load_wsgiapp = lambda: app gunicorn.cfg.set('bind', '%s:%s' % (host, port)) gunicorn.cfg.set('workers', workers) gunicorn.cfg.set('threads', workers) gunicorn.cfg.set('pidfile', None) gunicorn.cfg.set('worker_class', 'sync') gunicorn.cfg.set('keepalive', 10) gunicorn.cfg.set('accesslog', '-') gunicorn.cfg.set('errorlog', '-') gunicorn.cfg.set('reload', True) gunicorn.chdir() gunicorn.run()
gunicornのドキュメントによると、複数のスレッドが言及されている場合は、ワーカークラスがsyncからgthreadに変更されます。
PS:-
同期ワーカータイプを使用してスレッド設定を1より大きい値に設定しようとすると、代わりにgthreadワーカータイプが使用されます。
私の場合:
環境:Ubuntu18.04 + gunicorn + nginx + flask
私の仮想環境にpipinstall gunicorn [gevent]
gunicorn -b localhost:8000 -w 4 web:app
をgunicorn -b localhost:8000 -k gevent web:app
できます。
お互いに問題を解決するために多くのことをしてくれたここにいるすべての人に感謝します。 適切と思われる場合は、引き続きこの問題に投稿してください。
ただし、ここでGunicornにバグはないと思い、実行するアクションはないと思うので、この問題を閉じます。ただし、この問題のドキュメントを追加または改善しようとするPRのレビューを喜んでお手伝いします。メッセージをログに記録します。
私の意図を誤解しないでください。 Gunicornのバグが疑われ、引き続き議論したい場合は、そうしてください。 できれば、問題を再現するサンプルアプリケーションを使用して新しいチケットを開きます。 ただし、現時点では、この問題にはさまざまな問題、解決策、会話が多すぎて、非常に読みやすくなっています。
バッファリングリバースプロキシを前に配置せずにGunicornを実行すると、さまざまな理由でデフォルトの同期ワーカーでタイムアウトが発生します。 一般的なものは次のとおりです。
非同期またはスレッドワーカータイプに切り替えるか、Gunicornをバッファリングリバースプロキシの背後に配置することができます。 タイムアウトの原因が、独自のコードが外部APIをゆっくりと呼び出したり、期待どおりの重要な作業を行ったりしていることがわかっている場合は、 --timeout
オプションを増やすことができます。
これは、少なくとも2人のワーカーが必要であることを意味します。そうしないと、サーバーがデッドロックします。 要求は、サーバーが2番目の要求(キューに入れられる)に応答するまで待機します。 ワーカーごとに1つの同時リクエストを受け取ります。
…
2020年1月6日月曜日、02:45 alpinechicken、 @ 。 * >書いた:うん、あるルートが別のルートを呼び出す-それは悪いですか?
これは、ルートの戻り値として「リダイレクト」関数を呼び出す場合に当てはまりますか?
これは、ルートの戻り値として「リダイレクト」関数を呼び出す場合に当てはまりますか?
いいえ。フラスコリダイレクトはHTTPリダイレクトで応答し、ワーカーは新しいリクエストを自由に受け入れることができます。 クライアントは、この応答を確認したときに別の要求を行い、ワーカーの準備ができているときはいつでもこの要求を受け取ります。
gnuicornにワーカーを追加して、これを修正しました。
web: gunicorn --workers=3 BlocAPI:app --log-file -
理由はわかりません。
これは、彼がworkers=1 + (multiprocessing.cpu_count() * 2)
を設定した以前の@anilpaiコメントに関連していますか?
私はこれと同様の問題を抱えていました。 アプリケーションへのエントリポイントでエラーが発生したことが判明しました。 デバッグから、私は基本的にgunicornからflaskアプリを起動しているように見えました。その後、そのワーカーは30秒ごとにタイムアウトする無限の接続ループに入ります。
これは上記のすべてのユーザーに影響するわけではありませんが、一部のユーザーには影響する可能性があります。
私が持っていたgunicorn module.wsgi
実行している私のmodule/wsgi.py
ファイルで-
application = my_create_app_function()
application.run(host="0.0.0.0")
私が持っていたはずだったのに対し-
application = my_create_app_function()
if __name__ == "__main__":
application.run(host="0.0.0.0")
基本的に、gunicornを使用するときにapplication.run()
を呼び出さないでください。 gunicornの下の__name__
は"__main__"
にはなりませんが、Flaskにあるので、ローカルでデバッグできます。
gunicornのドキュメントでこれへの参照を見つけることができませんでしたが、これが一般的なエラーケースであると想像できたので、警告が必要な場合があります。
これはまだ発生しています。 Gunicornの呼び出しに--preload
を追加すると、問題が修正されました。
このバグはまだ修正されていませんか? 私はこの正確な振る舞いを観察しています。
Gunicornはsystemdで次のように始まります。
[Service]
PIDFile = /run/gunicorn.pid
WorkingDirectory = /home/pi/pyTest
ExecStart=/usr/local/bin/gunicorn app:app -b 0.0.0.0:80 --pid /run/gunicorn.pid
RuntimeDirectory=/home/pi/pyTest
Restart=always
KillSignal=SIGQUIT
Type=notify
StandardError=syslog
NotifyAccess=all
User=root
Group=root
ExecReload = /bin/kill -s HUP $MAINPID
ExecStop = /bin/kill -s TERM $MAINPID
ExecStopPost = /bin/rm -rf /run/gunicorn
PrivateTmp = true
ワーカープロセスは常にタイムアウトして再起動します。
Jul 10 15:19:20 raspberryVM gunicorn[10941]: [2020-07-10 15:19:20 -0700] [10941] [CRITICAL] WORKER TIMEOUT (pid:10944)
Jul 10 15:19:20 raspberryVM gunicorn[10941]: [2020-07-10 15:19:20 -0700] [10944] [INFO] Worker exiting (pid: 10944)
Jul 10 15:20:15 raspberryVM gunicorn[10941]: [2020-07-10 15:20:15 -0700] [10985] [INFO] Booting worker with pid: 10985
app.pyは些細なFlaskアプリです。
この問題は「修正しない」としてクローズされていますか?
私も同じ問題を抱えていました
しかし、デバッグ後、gunicornがDjango Appを起動しているときに、依存関係の1つが予想よりも長くかかっていたことがわかりました(私の場合は外部DB接続)。これにより、 gunicron
ワーカーがタイムアウトします。
接続の問題を解決すると、タイムアウトの問題も解決しました...
これは私の場合ではありません。 依存関係のない「Hello、World」タイプのアプリでテストしました。 だから私はまだこれに戸惑っていますが、Gunicornを長時間実行するスレッドを持つことは不可能のようです。 ワーカープロセスが再起動するため、長時間実行されているスレッドが強制終了されます。
@leonbrag
これはおそらくgunicornのバグではありません。 上記のスレッドで私の表彰を参照してください。 これは、ブラウザが空の「予測された」TCP接続を送信し、空のTCP接続から保護せずに少数の同期ワーカーのみでgunicornを実行することの副作用です。
長い(永続的な)ワーカースレッドでGunicornフラスコアプリをセットアップする適切な方法を示すリファレンスアーキテクチャ/デザインはありますか?
これがバグではない場合は、Gunicornのアーキテクチャ/設計のアーティファクトまたは制限のようです。
ワーカーの実行を永久に同期してクライアント接続を受け入れないのはなぜですか。 このようなワーカーは、必要に応じてソケットを閉じますが、終了せずに実行を継続します(したがって、ワーカースレッドは実行を継続します)。
@leonbrag
解決しようとしている問題について、より具体的にする必要があります。
このスレッドで説明されている問題は開発環境で発生します。最も簡単な解決策は、同期ワーカーを追加するか、スレッドワーカーを使用することです。
本番環境でこの問題を回避したい場合は、geventワーカーを使用するか、nginxをgunicornの前に配置することができます。
一部のPaaSは、Dockerコンテナの前にすでにnginxを配置しているため、心配する必要はありません。 この場合も、解決策はコンテキストと詳細によって異なります。
これは良い読み物です。
https://www.brianstorti.com/the-role-of-a-reverse-proxy-to-protect-your-application-against-slow-clients/
ドキュメントからデザインページを確認できます。 非同期ワーカーは1つです
長いタスクを実行する方法。
土2020年8月8日の18:00にleonbragの[email protected]は書きました:
セットアップの適切な方法を示すリファレンスアーキテクチャ/設計はありますか
長い(永続的な)ワーカースレッドを備えたGunicornフラスコアプリ?これがバグではない場合は、アーティファクトまたは制限のようです。
Gunicornのアーキテクチャ/デザイン。ワーカーの実行を永久に同期してクライアント接続を受け入れないのはなぜですか。 そのような
ワーカーは必要に応じてソケットを閉じますが、exItingなしで実行を継続します
(したがって、ワーカースレッドは引き続き実行されます)。—
あなたが言及されたので、あなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/benoitc/gunicorn/issues/1801#issuecomment-670944797 、
または購読を解除する
https://github.com/notifications/unsubscribe-auth/AAADRIWRQGIP3R5PMVJ5ENTR7VZA3ANCNFSM4FDLD5PA
。>>
私の携帯から送信
web:gunicorn --workers = 3 app:app --timeout 200 --log-file-
--timeoutを増やすことで問題を修正しました
Docker関連のtmpfsの問題については、#1388も参照してください。
ああ、Randallに感謝します。Dockerでgunicornを実行しているときに、gunicornの引数に--worker-tmp-dir /dev/shm
を追加するのを忘れました。
ところで、gunicornのキャッシュには64 Mbで十分ですか?
奇妙なことに、私は--worker-tmp-dir /dev/shm
を追加しましたが、それでも受け取ります:
[2020-11-27 21:01:42 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:17)
/dev/shm
がramfsであることを確認するために、ベンチマークを行いました。
次のパラメータは次のとおりです。
command: /bin/bash -c "cd /code/ && pipenv run gunicorn --worker-tmp-dir /dev/shm conf.wsgi:application --bind 0.0.0.0:8022 --workers 5 --worker-connections=1000"
PS:私はPyPyを使用しています
@attajuttのタイムアウトは素晴らしいですが、gunicornマスタープロセスが1000秒後にのみワーカープロセスのハングアップを検出するリスクがあり、多くのリクエストを見逃してしまいます。 また、数人の労働者のうち1人だけが電話を切ると、それを検出するのは困難になります。 私は少なくとも1000はしません。
@ivictborlmkに感謝します。 1000は参考用です。 それにもかかわらず、ロードされたアプリは完全に正常に実行されています。
私もこのエラーの問題が発生し、数回後、問題がおそらく引き起こされていることがわかりました:
GAEのようなクラウドにアプリをデプロイする場合、ヒントエラーは発生しません。
このケースソリューションを使用してエラーを表面化することができます: https :
502の不良ゲートウェイを発生させた場合。
おそらく2つの可能性があります:
ここで説明されている完全なsulotion: https ://www.datadoghq.com/blog/nginx-502-bad-gateway-errors-gunicorn/
[CRITICAL] WORKERTIMEOUTでエラーが発生した人を修正できることを願っています
このスレッドを見つけた人のために別の可能性を追加しています...
これは、DockerがWebアプリケーションに対して低すぎるリソース制約を課していることによっても発生する可能性があります。 たとえば、次の制約がありました。
services:
web_app:
image: blah-blah
deploy:
resources:
limits:
cpus: "0.25"
memory: 128M
これらは明らかにgunicorn
には低すぎるため、制約を削除するまで常に[CRITICAL] WORKER TIMEOUT
エラーが発生しました。
gunicornの場合、このリソースは完全に問題ありません。 しかし、あなたは確かにする必要があります
労働者の数とあなたに必要なリソースのための飛行機
応用。 128Mと0.25cpuは、Webアプリケーションとしては非常に低いようです
Pythonで書かれています...一般的に言えば、少なくとも1つのコア/ vcpuと
最低限でも512MBのRAM。
2021年3月26日金曜日02:14、Colton Hicks @ 。 * >書いた:
このスレッドを見つけた人のために別の可能性を追加しています...
これは、Dockerがリソースの制約を課していることによっても発生する可能性があります。
Webアプリケーションには低すぎます。 たとえば、私は次のようになりました
制約:サービス:
web_app:
画像:何とか何とか
配備:
資力:
制限:
CPU:「0.25」
メモリ:128Mそして、これらは明らかにgunicornには低すぎたので、私は常に[CRITICAL]を入手しました。
制約を削除するまで、WORKERTIMEOUTエラーが発生しました。—
あなたが言及されたので、あなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/benoitc/gunicorn/issues/1801#issuecomment-807855647 、
または購読を解除する
https://github.com/notifications/unsubscribe-auth/AAADRITPZB7BMA6QW7LFNVLTFPNV3ANCNFSM4FDLD5PA
。>>
私の携帯から送信
--timeout = 1000は私から働きました。 問題は、低CPUリソースのGCPマシンでした。 デフォルトのタイムアウトでローカルマシンで正常に動作しました。
最も参考になるコメント
geventでgunicornを使用しても、バグは修正されませんでした。