Sepertinya sudah ada beberapa laporan yang terkait dengan kesalahan [CRITICAL] WORKER TIMEOUT
tetapi terus bermunculan. Inilah masalah saya.
Saya menjalankan aplikasi Flask hello world ini.
from flask import Flask
application = Flask(__name__)
@application.route('/')
def hello_world():
return 'Hello, World!'
Perintah gunicorn adalah yang ini:
gunicorn -b 0.0.0.0:5000 --log-level=debug hello
Dan ini adalah output konsol:
[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
Bisakah Anda menjelaskan dengan jelas mengapa saya mendapatkan kesalahan dan jika itu diharapkan dalam contoh ini? Bagaimana cara memperbaikinya atau jika itu adalah perilaku yang diharapkan mengapa kesalahan kritis?
Kesalahan tidak diharapkan, tetapi tidak ada dari contoh Anda yang menunjukkan mengapa itu terjadi. Ceritakan lebih banyak tentang lingkungan Anda.
Ceritakan lebih banyak tentang lingkungan Anda.
Saya baru saja mereproduksi masalah pada pengaturan yang benar-benar baru, berikut langkah-langkahnya:
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
adalah aplikasi Flask yang sama persis dengan yang saya posting di laporan awal.
Di bawah ini adalah log lengkapnya.
~$ 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
@bigunya Saya pikir itu karena batas waktu default, pekerja Anda telah diam selama 30-an. http://docs.gunicorn.org/en/stable/settings.html#timeout
Dari catatan Anda,
[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)
Saya melihat hal yang sama: pekerja kehabisan waktu bahkan ketika tidak melayani permintaan, dengan pekerja sinkronisasi.
Untuk itu, log level kritis cukup membingungkan.
Coba gunakan pekerja Gevent yang bisa menyelesaikan ini.
Untuk itu, log level kritis cukup membingungkan.
Tepat, itu adalah pertanyaan awal saya: jika itu adalah perilaku yang diharapkan, mengapa kesalahan kritis?
Akan menyenangkan juga untuk mendapatkan beberapa latar belakang mengapa pekerja perlu di-restart, mungkin ini bisa ditambahkan ke dokumen Desain .
Saya melihat ini juga (direproduksi dengan menggunakan examples/test.py
dengan gunicorn test:app -b localhost:9595 --log-level=debug --timeout=5
) dan saya setuju bahwa level kritis agak membingungkan. Saya akan baik-baik saja mengubahnya ke level debug. @benoitc @tilgovi bagaimana menurutmu?
Saya pikir level info mungkin sedikit lebih baik.
Saya memiliki hal yang sama dengan MSYS2 di Win10 tetapi akhirnya bisa diselesaikan.
di notify() dari ...\gunicorn\workers\workertmp.py, os.fchmod digunakan pada awalnya. Tapi itu tidak bekerja di MSYS. Alih-alih os.fchmod, saya menggunakan os.utime. Kode diikuti. Saya pikir itu bisa bekerja untuk semua platform.
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 Saya tidak berharap pekerja keluar karena tidak ada permintaan yang terjadi. Kesalahan ini hanya akan terjadi jika pekerja tetap sibuk selama beberapa waktu > hingga batas waktu. Jadi kesalahannya kritis. Imo kami harus meningkatkan dokumentasi untuk memberikan lebih banyak kasus penggunaan dan tanggapan terhadap kesalahan tersebut.
Jika kesalahan masih terjadi saat pekerja tidak sibuk maka ada hal lain yang terjadi dan kami mungkin memiliki bug.
[EDIT]
Bug yang sama untuk saya.
Dengan Django 1.10 / gunicorn 19.6.0 / Python 2.7.15 di python2.7-alpine pada Debian 8.8 dan stock kernel 3.16, semuanya bekerja dengan baik.
Setelah memperbarui ke Django 1.11 dan gunicorn 19.8.1, para pekerja tetap gagal saat boot dengan [BATAS PEKERJA KRITIS].
Menurunkan versi gunicorn ke 19.6.0 tidak menyelesaikan masalah.
Kami memperbarui kernel host ke 4.9.0 (sudah dijadwalkan), dan para pekerja berhasil melakukan booting tanpa kesalahan.
Tetapi:
Kami akan mencoba gunicorn gevent untuk melihat apakah kami dapat membuat aplikasi kami kembali online.
Menggunakan gunicorn dengan gevent tidak memperbaiki bug.
ada pembaruan tentang masalah ini?
Sepertinya @neocolor mengidentifikasi bug nyata di bawah MSYS. Mungkin layak mendapat masalah terpisah.
@bigunya platform apa yang Anda jalankan? Saya telah mencoba mereproduksi dengan contoh sederhana dan saya tidak dapat melakukannya dengan mengikuti langkah-langkah yang dijelaskan di atas. Ini sesuai dengan pengalaman saya menjalankan banyak aplikasi dalam produksi pada banyak kerangka kerja. Sistem pemberitahuan pekerja tidak berubah baru-baru ini, sepengetahuan saya. Platform saya adalah Python 3.7 di MacOS 10.13.6, tetapi saya menjalankan Gunicorn dalam produksi dengan pekerja sinkronisasi untuk beberapa aplikasi di Python 2.7 dan 3.6.5 dan hanya melihat batas waktu pekerja ketika ada permintaan panjang yang sah yang memblokir pekerja.
Untuk @Tberdy : apa yang terjadi jika Anda mencoba mengatur --worker-tmp-dir
ke suatu tempat di luar sistem file tmpfs? Saya hanya ingin tahu apakah mungkin alpine atau buruh pelabuhan atau kombinasinya entah bagaimana mengganggu cara pekerja memberi tahu arbiter.
Lihat juga #1388 untuk masalah tmpfs terkait Docker.
saya punya masalah ini.
Saya memiliki masalah ini juga, sinkronisasi gunicorn bekerja dengan sangat baik sampai kemarin, tetapi mulai melaporkan, batas waktu pekerja [KRITIS] menggunakan gevent tampaknya menyelesaikan masalah saya, tetapi saya benar-benar ingin tahu mengapa ini terjadi.
@timoj58 @cjmash dapatkah Anda memberikan detail lebih lanjut tentang masalah ini? Bagaimana Anda menjalankan gunicorn (dalam vm?, opsi ...), sistem file mana, OS? Sesuatu yang dapat membantu untuk mereproduksi akan sangat membantu :)
@benoitc Saya menjalankan gunicorn untuk memulai proyek Django saya di kubernetes argumen gunicorn saya adalah --bind=$port --workers=7 --timeout=1200 --log-level=debug --access-logfile - error-logfile - "
kesalahan yang saya dapatkan dari log
```E [2018-08-09 21:47:56 +0000] [13] [INFO] Boot pekerja dengan pid: 13
E [2018-08-09 21:47:56 +0000] [14] [INFO] Boot pekerja dengan pid: 14
E [2018-08-09 21:47:56 +0000] [12] [INFO] Boot pekerja dengan pid: 12
E [2018-08-09 21:47:56 +0000] [1] [DEBUG] 7 pekerja
E [2018-08-09 21:47:56 +0000] [11] [INFO] Boot pekerja dengan pid: 11
E [2018-08-09 21:47:55 +0000] [10] [INFO] Boot pekerja dengan pid: 10
E [2018-08-09 21:47:55 +0000] [9] [INFO] Boot pekerja dengan pid: 9
E [2018-08-09 21:47:55 +0000] [8] [INFO] Boot pekerja dengan pid: 8
E [2018-08-09 21:47:55 +0000] [1] [INFO] Menggunakan pekerja: sinkronisasi
E [2018-08-09 21:47:55 +0000] [1] [INFO] Mendengarkan di: http://0.0.0.0 :4040 (1)
E [2018-08-09 21:47:55 +0000] [1] [DEBUG] Arbiter boot
E [2018-08-09 21:47:55 +0000] [1] [INFO] Memulai gunicorn 19.7.1
E raw_paste_global_conf: []
Sandi E: TLSv1
E do_handshake_on_connect: Salah
E suppress_ragged_eofs: Benar
E ca_certs: Tidak ada
E cert_reqs: 0
E ssl_version: 2
E sertifikat: Tidak ada
File kunci E: Tidak ada
E proxy_allow_ips: ['127.0.0.1']
E proxy_protocol: Salah
E saat_keluar:
E nworkers_changed:
E pekerja_keluar:
E anak_keluar:
E post_request:
E pra_permintaan:
E pra_exec:
Pembatalan_pekerja:
E pekerja_int:
E post_worker_init:
E post_fork:
E pre_fork:
E kapan_siap:
E on_reload:
E on_starting:
E pasta: Tidak ada
E pythonpath: Tidak ada
E default_proc_name: art.wsgi
E proc_name: Tidak ada
E statsd_prefix:
E statsd_host: Tidak ada
E enable_stdio_inheritance: Salah
E syslog_facility: pengguna
E syslog_prefix: Tidak ada
E syslog: Salah
E syslog_addr: udp://localhost :514
E logconfig: Tidak ada
E logger_class: gunicorn.glogging.Logger
E capture_output: Salah
E loglevel: debug
E kesalahan log: -
E access_log_format: %(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%( sebagai"
E akses log: -
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: Tidak ada
E initgroups: Salah
E umask: 0
Grup E: 0
Pengguna E: 0
E worker_tmp_dir: Tidak ada
E pidfile: Tidak ada
E raw_env: []
E daemon: Salah
E chdir: /usr/src/app
E sendfile: Tidak ada
E preload_app: Salah
E check_config: Salah
E memuntahkan: Salah
E reload_engine: otomatis
E isi ulang: Salah
E limit_request_field_size: 8190
E limit_request_fields: 100
E limit_request_line: 4094
E tetap hidup: 2
E graceful_timeout: 30
E batas waktu: 1200
E max_requests_jitter: 0
E max_requests: 0
E pekerja_koneksi: 1000
E benang: 1
E worker_class: sinkronisasi
E pekerja: 7
Tumpukan E: 2048
E mengikat: ['0.0.0.0:4040']
Konfigurasi E: Tidak ada
E [2018-08-09 21:47:55 +0000] [1] [DEBUG] Konfigurasi saat ini:
I Tidak ada migrasi untuk diterapkan.
I Menjalankan migrasi:
Saya Menerapkan semua migrasi: admin, auth, tipe konten, inti, dasbor, jet, oauth2_provider, sesi
I Operasi yang harus dilakukan:
E [2018-08-09 21:47:20 +0000] [13] [INFO] Pekerja keluar (pid: 13)
E os.path.dirname(os.path.dirname(__file__)), '.env'))
E /usr/src/app/art/wsgi.py:19: UserWarning: Tidak membaca /usr/src/app/.env - tidak ada.
E [2018-08-09 21:47:00 +0000] [21] [INFO] Boot pekerja dengan pid: 21
E [2018-08-09 21:47:00 +0000] [1] [INFO] Penanganan sinyal: term
E [2018-08-09 21:46:35 +0000] [12] [INFO] Boot pekerja dengan pid: 12
E [2018-08-09 21:46:34 +0000] [13] [INFO] Boot pekerja dengan pid: 13
E [2018-08-09 21:46:34 +0000] [11] [INFO] Boot pekerja dengan pid: 11
E [2018-08-09 21:46:34 +0000] [1] [DEBUG] 7 pekerja
E [2018-08-09 21:46:34 +0000] [10] [INFO] Boot pekerja dengan pid: 10
E [2018-08-09 21:46:34 +0000] [9] [INFO] Boot pekerja dengan pid: 9
E [2018-08-09 21:46:34 +0000] [8] [INFO] Boot pekerja dengan pid: 8
E [2018-08-09 21:46:34 +0000] [7] [INFO] Boot pekerja dengan pid: 7
E [2018-08-09 21:46:34 +0000] [1] [INFO] Menggunakan pekerja: sinkronisasi
E [2018-08-09 21:46:34 +0000] [1] [INFO] Mendengarkan di: http://0.0.0.0 :4040 (1)
E [2018-08-09 21:46:34 +0000] [1] [DEBUG] Arbiter boot
E [2018-08-09 21:46:34 +0000] [1] [INFO] Memulai gunicorn 19.7.1
E raw_paste_global_conf: []
Sandi E: TLSv1
E do_handshake_on_connect: Salah
E suppress_ragged_eofs: Benar
E ca_certs: Tidak ada
E cert_reqs: 0
E ssl_version: 2
E sertifikat: Tidak ada
File kunci E: Tidak ada
E proxy_allow_ips: ['127.0.0.1']
E proxy_protocol: Salah
E saat_keluar:
E nworkers_changed:
E pekerja_keluar:
E anak_keluar:
E post_request:
E pra_permintaan:
E pra_exec:
Pembatalan_pekerja:
E pekerja_int:
E post_worker_init:
E post_fork:
E pre_fork:
E kapan_siap:
E on_reload:
E on_starting:
E pasta: Tidak ada
E pythonpath: Tidak ada
E default_proc_name: art.wsgi
E proc_name: Tidak ada
E statsd_prefix:
E statsd_host: Tidak ada
E enable_stdio_inheritance: Salah
E syslog_facility: pengguna
E syslog_prefix: Tidak ada
E syslog: Salah
E syslog_addr: udp://localhost :514
E logconfig: Tidak ada
E logger_class: gunicorn.glogging.Logger
E capture_output: Salah
E loglevel: debug
E kesalahan log: -
E access_log_format: %(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%( sebagai"
E akses log: -
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: Tidak ada
E initgroups: Salah
E umask: 0
Grup E: 0
Pengguna E: 0
E worker_tmp_dir: Tidak ada
E pidfile: Tidak ada
E raw_env: []
E daemon: Salah
E chdir: /usr/src/app
E sendfile: Tidak ada
E preload_app: Salah
E check_config: Salah
E memuntahkan: Salah
E reload_engine: otomatis
E isi ulang: Salah
E limit_request_field_size: 8190
E limit_request_fields: 100
E limit_request_line: 4094
E tetap hidup: 2
E graceful_timeout: 30
E batas waktu: 1200
E max_requests_jitter: 0
E max_requests: 0
E pekerja_koneksi: 1000
E benang: 1
E worker_class: sinkronisasi
E pekerja: 7
Tumpukan E: 2048
E mengikat: ['0.0.0.0:4040']
Konfigurasi E: Tidak ada
E [2018-08-09 21:46:34 +0000] [1] [DEBUG] Konfigurasi saat ini:
```
Saya berjuang sedikit untuk mereproduksi masalah kali ini tetapi masih ada di versi terbaru gunicorn 19.9.0.
Langkah-langkah untuk mereproduksinya persis sama seperti yang saya jelaskan di posting ini .
Sistem saya adalah Arch Linux x86_64 GNU/Linux (kernel 4.17.2-1-ARCH), Python 3.6.5
Berikut adalah jejak log baru.
~$ 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
Seperti sebelumnya untuk mengujinya, saya hanya menekan http://0.0.0.0 :5000/ di Chromium.
Di bawah ini adalah konten Pipfile dan Pipfile.lock agar Anda dapat melihat lingkungan yang tepat.
[[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": {}
}
Sekedar informasi, saya juga sering melihat kegagalan ini dengan:
nohup gunicorn -w 8 --access-logfile=- --bind 127.0.0.1:5000 wsgi &
Saya hanya punya wsgi.py yang memiliki
from chart_api import application
if __name__ == "__main__":
application.run()
Beri tahu saya jika ada sesuatu yang Anda ingin saya coba/eksperimen atau jika ada spesifik dalam log yang Anda ingin saya periksa. Saya menjalankan flask pada VM GCP.
maaf karena terlambat membalas. Saya menjalankannya sebagai
gunicorn --log-file=/home/ubuntu/log/gunicorn.log prediktor_ api:app -b localhost:5000 &
saya memang menggunakan pengaturan gevent dll, tetapi saya telah mengubah desain saya tentang apa yang saya butuhkan ini untuk mengatasi masalah, maka pengaturan dasar di atas (yang juga gagal tetapi ini diharapkan karena tidak ada gevent)
Python versi 3.6
env: aws tensorflow_p36 dioptimalkan (ubuntu)
nginx berada di depan gunicorn, yang menjalankan aplikasi flask.
labu versi 1.0.2
nginx versi 1.10.3
gunicorn versi 19.9.0
Saya memang mengubah batas waktu nginx juga jika ini yang menyebabkannya.
Menghadapi masalah yang sama dengan server gunicorn
# gunicorn Applicat ionServer:app -b 0.0.0.0:6001 -w 8 --threads 4 --backlog 2048 \
# --timeout 120 --graceful-timeout 60 --access-logfile logs/access.log \
Labu == 0.12.1
gunicorn==19.7.1
ketika saya memulai server dengan perintah di atas, sistem saya membeku untuk beberapa waktu dan pid pekerja terus boot, meskipun saya mempertahankan batas waktu 120 detik, dan server tidak menerima satu permintaan.
Setiap pembaruan tentang masalah ini? Saya memiliki masalah yang sama
[KRITIS] WAKTU PEKERJA
Ingin tahu apakah ada yang berhasil mereproduksi ini dalam gambar Docker?
Juga melihat ini ketika mencoba mengimplementasikan pekerja ddtrace-run datadog pada aplikasi yang ada dimulai dengan gunicorn -k gevent --threads 4.
Jejak lucu dari SystemExit yang belum pernah saya lihat sebelumnya juga...
[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
Saya dapat mengatasi masalah ini dengan mencocokkan jumlah pekerja dan jumlah utas.
Saya telah menetapkan workers = (2 * cpu_count) + 1
dan tidak mengatur utas.
Setelah saya mengubah threads = workers
, semuanya mulai berfungsi dengan baik. Untuk jaga-jaga, jika ini membantu seseorang.
Begini tampilannya sekarang
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()
Saya mengalami masalah ini saat menjalankan Django dengan wadah Docker tunggal di AWS Elastic Beanstalk. Saya menyelesaikan masalah dengan memperbaiki grup keamanan saya untuk memastikan instans EC2 saya dapat berbicara dengan instans RDS saya. Saya menyadari ini mungkin bukan solusi untuk 99% orang tentang masalah ini, tetapi saya meninggalkan catatan ini untuk membantu orang lain menghindari membuang waktu berjam-jam jatuh ke lubang kelinci ini.
Dalam kasus saya, masalah diselesaikan dengan melakukan systemctl daemon-reload
.
Singkat cerita saya tahu batas waktu default pada 30 detik, tetapi tidak dapat mengubahnya sampai saya pikir saya harus memuat ulang daemon systemd untuk menerapkan perubahan ke layanan.
@bigunyak @benoitc @tilgovi
Setelah pengejaran angsa google yang panjang dan beberapa eksperimen, saya yakin akar penyebab masalah ini adalah "layanan prakoneksi/prediksi" chrome (yang diaktifkan secara default di Chrome dan Chromium).
@jeiting menulis dengan baik tentang masalah ini
https://hackernoon.com/chrome-preconnect-breaks-singly-threaded-servers-95944be16400
Beberapa bacaan tambahan:
https://github.com/corydolphin/flask-cors/issues/147
https://github.com/pallets/flask/issues/2169
TLDR
Dalam beberapa kasus, Chrome/Chromium membuka dan menahan koneksi TCP "kosong" (yaitu memprediksi bahwa itu akan segera mengambil sumber daya lain). Jika koneksi TCP "kosong" mengenai server gunicorn Anda terlebih dahulu, maka permintaan "asli" berikutnya dari chrome dapat terhenti di belakang permintaan "kosong" hingga pekerja yang menangani permintaan "kosong" habis waktu. Ini lebih mungkin terjadi jika Anda hanya menjalankan satu pekerja sinkronisasi di gunicorn. Tetapi seperti yang ditemukan oleh eksperimen saya, itu bisa terjadi bahkan jika Anda menjalankan beberapa pekerja sinkronisasi.
Lingkunganku
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
......
Percobaan 1
Konfigurasi Gunicorn: 1 pekerja sinkronisasi (batas waktu default 30 detik)
Firefox: Di hampir setiap pemuatan halaman reaksi, permintaan CORS OPTIONS diblokir selama 5 detik, dan kemudian berhasil.
Chromium: Pada SETIAP pemuatan halaman reaksi, permintaan CORS OPTIONS diblokir selama 1,5 menit!!!! dan kemudian berhasil.
Chromium (layanan prediksi dinonaktifkan): Semuanya dimuat dengan baik
Chrome: Semuanya dimuat dengan baik
Percobaan 2
Konfigurasi Gunicorn: 4 pekerja sinkronisasi (batas waktu default 30 detik)
Firefox: Semuanya dimuat dengan baik
Chromium: Pada setiap pemuatan halaman reaksi ke-3, permintaan CORS OPTIONS diblokir selama 30 detik dan kemudian berhasil.
Chromium (layanan prediksi dinonaktifkan): Semuanya dimuat dengan baik
Chrome: Semuanya dimuat dengan baik
Percobaan 3
Konfigurasi Gunicorn: 8 pekerja sinkronisasi (batas waktu default 30 detik)
Firefox: Semuanya dimuat dengan baik
Chromium: Semuanya dimuat dengan baik
Chrome: Semuanya dimuat dengan baik
Percobaan 4
Jalankan server dev flask dengan threaded=True
Firefox: Semuanya dimuat dengan baik
Chromium: Semuanya dimuat dengan baik
Chrome: Semuanya dimuat dengan baik
Ringkasan Eksperimen
Larutan
Dalam Produksi: Perbaikan termudah adalah meletakkan nginx di depan gunicorn. Jika Anda ingin memahami mengapa nginx memecahkan masalah ini, inilah artikel bagus yang menjelaskannya: https://www.brianstorti.com/the-role-of-a-reverse-proxy-to-protect-your-application-against -pelambatan-klien/
Di dev: Perbaikan termudah adalah menjalankan server flask dev dengan threaded=True
. Atau Anda dapat menonaktifkan layanan prediksi di Chrome/Chromium.
peningkatan debug gunicorn
Untuk membantu men-debug masalah seperti ini di masa mendatang, sebaiknya tambahkan pernyataan log debug di sebelah panggilan select()
dan accept()
di pekerja sinkronisasi.
https://github.com/benoitc/gunicorn/blob/e974f30517261b2bc95cfb2017a8688f367c8bf3/gunicorn/workers/sync.py#L26
https://github.com/benoitc/gunicorn/blob/e974f30517261b2bc95cfb2017a8688f367c8bf3/gunicorn/workers/sync.py#L34
Ini akan menunjukkan bahwa seorang pekerja telah menerima koneksi TCP baru, tetapi tidak menerima data apa pun.
@asnisarenko super menulis, terima kasih. #1929 adalah kasus lain yang tidak biasa dari klien lambat yang menghasilkan gejala serupa di server utas tunggal - dalam hal ini, jabat tangan TLS ke port non-TLS terlihat seperti klien penulisan lambat, karena gagal mengirim header yang masuk akal dengan cepat .
Mungkin Gunicorn, untuk pekerja sinkronisasi utas tunggal akan membutuhkan beberapa merdu baru, penurunan klien yang agresif untuk klien yang gagal mengirim setidaknya baris tajuk permintaan pertama, jika tidak semua tajuk, dalam waktu yang wajar.
Jika ini terjadi di aplikasi Anda, Anda dapat menambahkan beberapa kode diagnostik sementara:
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)
Semoga ini akan mengungkapkan di mana aplikasi Anda hang.
Sebagai contoh, saya entah bagaimana berhasil import flask
sebelum gevent.monkey.patch_all()
dan Flask saya app._before_request_lock
akhirnya menjadi kunci non-gevent (yaitu polos tidak ditambal threading.Lock
). Dalam kasus seperti itu, dua permintaan secara berurutan pada permulaan aplikasi akan menyebabkannya macet (permintaan kedua akan mengunci seluruh utas). Tapi ini adalah bug saya, dan bug Anda mungkin berbeda.
@asnisarenko Saya tidak yakin mengapa Anda mengalami hang. Anda benar-benar _tidak_ membutuhkan pekerja per koneksi, karena setiap pekerja dapat secara kooperatif menangani ribuan koneksi (selama kode penanganan tidak memonopoli CPU/mengunci seluruh utas). Secara khusus, jika browser menghentikan permintaan, itu berarti bahwa ketika gunicorn read()
s dari soket, itu akan memblokir greenlet, tetapi karena read
harus ditambal dengan monyet, itu akan menghasilkan greenlet lainnya.
@ikonst
Masalah ini berbicara tentang menjalankan gunicorn dengan konfigurasi default. Kelas pekerja default adalah sync
http://docs.gunicorn.org/en/stable/settings.html#worker -class
sync
pekerja menggunakan model pre-fork dan setiap pekerja memproses satu koneksi/permintaan TCP pada satu waktu.
Saya tidak tahu apa yang menyebabkan ini bagi saya, tetapi beralih dari tipe pekerja default sync
ke eventlet
menyelesaikan masalah:
CMD pipenv run gunicorn webapp -b 0.0.0.0:8080 -k eventlet
Semoga berhasil.
Mungkin ini hanya akan membantu saya, tetapi karena saya membutuhkan waktu 7 jam untuk men-debug masalah ini di pihak saya (aplikasi Flask/Gunicorn berjalan di Docker pada EC2), jika saya dapat menyisihkan sakit kepala ini untuk beberapa orang, ini adalah kemenangan kecil.
Batas memori penampung yang terlalu rendah. kehabisan waktu tanpa (tampaknya) tanpa alasan.
Jika saya memiliki kebocoran memori di masa depan, saya akan mencoba untuk menempatkan batas memori yang lebih tinggi, tetapi untuk saat ini, tidak ada batasan yang akan dilakukan.
Terima kasih
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)
Anda sangat membantu saya. EH )))
Ke mana perginya metode trace_on_abort()
ini? Dalam file kode aplikasi? Apakah perlu anotasi?
@mattg-vbt tambahkan ini ke awal aplikasi Anda saat Anda perlu men-debug, dan hapus setelah Anda selesai men-debug
@ikonst Saya menambahkan ini ke aplikasi saya, tetapi saya tidak melihatnya terkena. Saya mendapatkan batas waktu pekerja, tetapi metode ini tidak berhasil.
@mattg-vbt dapatkah Anda mencoba melakukan kill -ABRT $pid
untuk melihat fungsi print_trace
dipanggil? (idenya adalah Anda akan mendapatkan SIGABRT dari werkzeug ketika pekerja Anda kehabisan waktu, tetapi pertama-tama mari kita periksa apakah itu dipanggil sama sekali)
@asnisarenko untuk yang kurang paham di antara kita, bagaimana cara memperbarui procfile?
web gunicorn app:app -k gevent --worker-connections 1000
?
@SumNeuron
Jika Anda menggunakan pekerja gevent Anda (bukan pekerja sinkronisasi) maka Anda seharusnya tidak mengalami masalah ini. Jadi perintah yang Anda posting tampaknya baik-baik saja.
Saya mendapatkan masalah ini dengan pekerja gevent hanya setelah inisialisasi, yang agak mengganggu karena saya sedang memproses beberapa tugas sebelum meluncurkan aplikasi saya. Tapi saya menetapkan batas waktu yang tinggi untuk saat ini.
Saya telah memposting repo pengujian yang dapat direproduksi di sini: https://github.com/zamponotiropita/test-gunicorn-worker-timeout -> test_0 gagal, test_1 dan test_2 lulus
@zamponotiropita Apakah Anda mencoba melakukan ini per pekerja atau per aplikasi sebelum forking?
@ikonst silakan periksa file run run.sh
, ini per pekerja. Masalahnya tidak muncul dengan pramuat, tetapi saya mengalami masalah saat menghubungkan ke database saat memuat, karena objek aplikasi (dan bersama-sama dengan koneksi database) disalin dan melewati proses saat forking -> database saya tidak bisa menangani koneksi master dan pekerja yang identik, dan saya tidak dapat menemukan solusi
Saya mengalami masalah serupa. Saya mencoba menghasilkan banyak data saat itu juga dengan Flask menggunakan
metode ini , dan gagal karena waktu pekerja habis setelah apa pun yang ditetapkan di --timeout
kedaluwarsa. Contoh minimal untuk direproduksi:
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')
Kemudian jalankan gunicorn --timeout 10 test_gunicorn_timeout:app
dan ketika meminta localhost:8000
setelah 10 detik Anda mendapatkan
[CRITICAL] WORKER TIMEOUT
.
Saya juga mencoba menjalankan dengan -k gevent
dan -k eventlet
dan tidak ada yang berubah.
Saya menggunakan windows 10 Pro. Dengan komposisi buruh pelabuhan
gunicorn app -b 0.0.0.0:8000 -k gevent
Bekerja untuk saya dengan menginstal gevent di wadah python saya
Bagaimana cara menginstal gevent
Kemudian jalankan
gunicorn --timeout 10 test_gunicorn_timeout:app
dan ketika memintalocalhost:8000
setelah 10 detik Anda mendapatkan
[CRITICAL] WORKER TIMEOUT
.Saya juga mencoba menjalankan dengan
-k gevent
dan-k eventlet
dan tidak ada yang berubah.
@ltskv
sudahkah Anda menemukan solusi untuk masalah TIMEOUT PEKERJA [KRITIS]?
Saya memiliki masalah serupa dengan titik akhir streaming labu yang saya coba gunakan di heroku (yang menggunakan gunicorn). Di sana, frontend proxy seharusnya menjaga koneksi tetap hidup selama beberapa data dikirim dalam 30 detik, tetapi tampaknya gunicorn hanya mematikan proses jika belum selesai dalam 30 detik meskipun masih berjalan dan menghasilkan data.
Dokumentasi gunicorn tidak sepenuhnya jelas bagi saya dalam hal ini. Untuk --timeout dikatakan bahwa Workers silent for more than this many seconds are killed and restarted.
Tetapi tampaknya pekerja terbunuh setelah 30 detik meskipun mereka masih menghasilkan data?
Dokumentasi gunicorn tidak sepenuhnya jelas bagi saya dalam hal ini. Untuk --timeout dikatakan bahwa Pekerja yang diam selama lebih dari beberapa detik ini terbunuh dan dimulai kembali. Tetapi tampaknya pekerja terbunuh setelah 30 detik meskipun mereka masih menghasilkan data?
@kurt-hectic bahwa dokumentasi harus ditingkatkan. Dengan diam, yang kami maksud adalah diam dari perspektif proses arbiter, yang berkomunikasi dengan para pekerja melalui file sementara. Jika pekerja sibuk mengirim data, itu tidak memperbarui file itu. Dari sudut pandang arbiter, pekerja tersebut kehilangan detak jantungnya.
Lihat juga # 1974.
Menggunakan pekerja apa pun selain pekerja default, pekerja sinkron harus mengurangi masalah dengan streaming badan besar, karena pekerja lain akan mempercepat file sementara bahkan ketika mereka menangani permintaan.
@kurt-hectic Saya memeriksa ulang sekali lagi opsi -k gevent
dan memasukkan sleep(0)
antara iterasi generator dan itu benar-benar berfungsi untuk saya (saya tidak yakin mengapa itu tidak berfungsi pada saat itu Saya memposting pertanyaan itu).
--waktu habis=5
Ini adalah penyebab paling umum dari masalah ini.
Saya harap solusi saya dapat membantu Anda. Saya menemui masalah batas waktu pekerja kritis ini beberapa hari yang lalu dan mencoba beberapa solusi. Sekarang bekerja dengan baik.
Berikut pemahaman dan solusi saya:
Gagal mem-boot pekerja karena perlu lebih banyak waktu untuk memuat paket, seperti backend tensorflow, untuk memulai layanan. Jadi ketika Anda mengalami waktu boot aplikasi yang lambat, coba aktifkan opsi pramuat di gunicorn (Lihat https://devcenter.heroku.com/articles/python-gunicorn#advanced-configuration).
gunicorn halo: aplikasi --preload
Batas waktu default adalah 30 detik. Jika aplikasi Anda benar-benar membutuhkan banyak waktu untuk menyelesaikan api, tambah batas waktu.
gunicorn halo: aplikasi --batas waktu 10
Namun, dari sudut pandang saya, tidak masuk akal jika api membutuhkan lebih dari 1 menit untuk menyelesaikannya. Jika demikian, cobalah untuk membuat beberapa kemajuan dalam kode Anda.
Saya menghadapi masalah yang sama hari ini. Dalam kasus saya, api membutuhkan waktu sekitar satu menit untuk menghitung data dan kembali ke klien, yang mengakibatkan kesalahan CRITICAL WORKER TIMEOUT. Saya menyelesaikannya dengan meningkatkan batas waktu untuk gunicorn menjadi lebih dari satu menit - berhasil, tidak melihat masalah kembali. Semoga ini membantu. Saya menggunakan uvicorn.workers.UvicornWorker.
Saya memperbaikinya dengan menambahkan pekerja tambahan ke gnuicorn:
web: gunicorn --workers=3 BlocAPI:app --log-file -
Tidak tahu mengapa.
Mungkin Anda mengalami kebuntuan? Apakah aplikasi Anda membuat permintaan untuk dirinya sendiri?
Pada Minggu, 5 Januari 2020, 10:52 alpinechicken, [email protected] menulis:
Saya memperbaikinya dengan menambahkan pekerja tambahan ke gnuicorn:
web: gunicorn --workers=3 BlocAPI:app --log-file -
Tidak tahu mengapa.
—
Anda menerima ini karena Anda berkomentar.
Balas email ini secara langsung, lihat di GitHub
, https://github.com/benoitc/gunicorn/issues/1801?email_source=notifications&email_token=AAAEQJVQRCW3C63EZJWIN5DQ4G3WTA5CNFSM4FDLD5PKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LDNMVX
atau berhenti berlangganan
https://github.com/notifications/unsubscribe-auth/AAAEQJXZM4NLK56DZMFSZALQ4G3WTANCNFSM4FDLD5PA
.
Ya, satu rute memanggil yang lain - apakah itu buruk?
Ini berarti Anda membutuhkan setidaknya dua pekerja jika tidak, server Anda akan
jalan buntu. Permintaan akan menunggu hingga server merespons yang kedua
permintaan (yang akan diantrekan).
Anda mendapatkan satu permintaan bersamaan per pekerja.
Pada Senin, 6 Januari 2020, 02:45 alpinechicken, [email protected] menulis:
Ya, satu rute memanggil yang lain - apakah itu buruk?
—
Anda menerima ini karena Anda berkomentar.
Balas email ini secara langsung, lihat di GitHub
https://github.com/benoitc/gunicorn/issues/1801?email_source=notifications&email_token=AAAEQJSFEFBBI6AMZJCM4C3Q4KLOJA5CNFSM4FDLD5PKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LENMVXHJKTLOIWWS
atau berhenti berlangganan
https://github.com/notifications/unsubscribe-auth/AAAEQJXTCPOFIZJU5PUPOODQ4KLOJANCNFSM4FDLD5PA
.
Ah itu masuk akal. Terima kasih!
Pada Selasa, 7 Januari 2020 pukul 06:23 bobf [email protected] menulis:
Ini berarti Anda membutuhkan setidaknya dua pekerja jika tidak, server Anda akan
jalan buntu. Permintaan akan menunggu hingga server merespons yang kedua
permintaan (yang akan diantrekan).Anda mendapatkan satu permintaan bersamaan per pekerja.
Pada Senin, 6 Januari 2020, 02:45 alpinechicken, [email protected] menulis:
Ya, satu rute memanggil yang lain - apakah itu buruk?
—
Anda menerima ini karena Anda berkomentar.
Balas email ini secara langsung, lihat di GitHub
<
https://github.com/benoitc/gunicorn/issues/1801?email_source=notifications&email_token=AAAEQJSFEFBBI6AMZJCM4C3Q4KLOJA5CNFSM4FDLD5PKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LENMVXHJKT05
,
atau berhenti berlangganan
<
https://github.com/notifications/unsubscribe-auth/AAAEQJXTCPOFIZJU5PUPOODQ4KLOJANCNFSM4FDLD5PA.
—
Anda menerima ini karena Anda berkomentar.
Balas email ini secara langsung, lihat di GitHub
Https://github.com/benoitc/gunicorn/issues/1801?email_source=notifications&email_token=AAH2WRPVPVO2EJ53BKQW5B3Q4OHLRA5CNFSM4FDLD5PKYY3PNVWWK3TUL52HS4DFVREXG43VMVBZQ12GDN5VJW57ZQEILODN5VMXH2990issue
atau berhenti berlangganan
https://github.com/notifications/unsubscribe-auth/AAH2WRM2LLIB4O6OHCU5UG3Q4OHLRANCNFSM4FDLD5PA
.
pekerja_kelas', 'sinkronisasi')
Saya dapat mengatasi masalah ini dengan mencocokkan jumlah pekerja dan jumlah utas.
Saya telah menetapkan
workers = (2 * cpu_count) + 1
dan tidak mengatur utas.Setelah saya mengubah
threads = workers
, semuanya mulai berfungsi dengan baik. Untuk jaga-jaga, jika ini membantu seseorang.Begini tampilannya sekarang
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()
Sesuai dokumen gunicorn, itu mengubah kelas pekerja dari sinkronisasi ke gthread jika lebih dari satu utas disebutkan.
PS:-
Jika Anda mencoba menggunakan jenis pekerja sinkronisasi dan menyetel setelan utas ke lebih dari 1, jenis pekerja gthread akan digunakan sebagai gantinya.
kasus saya:
Lingkungan: Ubuntu18.04+ gunicorn+ nginx +flask
pip install gunicorn[gevent] di lingkungan virtual saya
Ubah gunicorn -b localhost:8000 -w 4 web:app
menjadi gunicorn -b localhost:8000 -k gevent web:app
Berhasil.
Terima kasih kepada semua orang di sini yang telah melakukan begitu banyak untuk membantu satu sama lain menyelesaikan masalah mereka. Silakan lanjutkan posting untuk masalah ini jika tampaknya sesuai.
Namun, saya menutup masalah ini karena menurut saya tidak ada bug di Gunicorn di sini dan menurut saya tidak ada tindakan yang harus diambil, meskipun saya dengan senang hati akan membantu meninjau PR yang mencoba menambahkan dokumentasi untuk ini entah bagaimana atau meningkatkannya pesan log.
Tolong jangan salah paham dengan niat saya. Jika Anda mencurigai adanya bug di Gunicorn dan ingin melanjutkan diskusi, silakan lakukan. Sebaiknya, buka tiket baru dengan aplikasi contoh yang mereproduksi masalah Anda. Namun, pada titik ini, ada terlalu banyak masalah, resolusi, dan percakapan yang berbeda dalam masalah ini sehingga sulit dibaca.
Jika Anda menjalankan Gunicorn tanpa proxy terbalik buffering di depannya, Anda _akan_ mendapatkan batas waktu dengan default, sinkronkan pekerja untuk sejumlah alasan. Yang umum adalah:
Anda dapat beralih ke jenis pekerja asinkron atau berulir, atau Anda dapat menempatkan Gunicorn di belakang proxy terbalik buffering. Jika Anda mengetahui bahwa waktu tunggu Anda disebabkan oleh kode Anda sendiri yang membuat panggilan lambat ke API eksternal atau melakukan pekerjaan signifikan yang Anda harapkan, Anda dapat meningkatkan opsi --timeout
.
Ini berarti Anda membutuhkan setidaknya dua pekerja jika tidak, server Anda akan menemui jalan buntu. Permintaan akan menunggu hingga server merespons permintaan kedua (yang akan diantrekan). Anda mendapatkan satu permintaan bersamaan per pekerja.
…
Pada Sen, 6 Jan 2020, 02:45 alpinechicken, @ . * > menulis: Ya, satu rute memanggil yang lain - apakah itu buruk?
Apakah ini kasusnya ketika memanggil fungsi 'redirect' sebagai nilai balik untuk sebuah rute?
Apakah ini kasusnya ketika memanggil fungsi 'redirect' sebagai nilai balik untuk sebuah rute?
Tidak. Pengalihan labu merespons dengan pengalihan HTTP dan pekerja kemudian bebas menerima permintaan baru. Klien membuat permintaan lain ketika melihat respons ini dan setiap kali pekerja siap akan menerima permintaan ini.
Saya memperbaikinya dengan menambahkan pekerja tambahan ke gnuicorn:
web: gunicorn --workers=3 BlocAPI:app --log-file -
Tidak tahu mengapa.
Apakah ini terkait dengan komentar @anilpai sebelumnya di mana ia menetapkan workers=1 + (multiprocessing.cpu_count() * 2)
.. ?
Saya memiliki masalah serupa dengan ini. Ternyata saya memiliki kesalahan di titik masuk saya ke aplikasi. Dari debugging, sepertinya saya pada dasarnya meluncurkan aplikasi flask dari gunicorn, yang pekerjanya kemudian memasuki loop koneksi tak terbatas yang habis setiap 30 detik.
Saya yakin ini tidak memengaruhi semua pengguna di atas, tetapi mungkin memengaruhi beberapa pengguna.
Dalam file module/wsgi.py
saya yang saya jalankan dengan gunicorn module.wsgi
saya miliki -
application = my_create_app_function()
application.run(host="0.0.0.0")
Padahal saya seharusnya sudah -
application = my_create_app_function()
if __name__ == "__main__":
application.run(host="0.0.0.0")
Pada dasarnya, Anda tidak ingin memanggil application.run()
saat menggunakan gunicorn. __name__
bawah gunicorn tidak akan menjadi "__main__"
, tetapi akan berada di Flask, jadi Anda masih dapat men-debug secara lokal.
Saya tidak dapat menemukan referensi untuk ini di dokumen gunicorn, tetapi dapat membayangkannya sebagai kasus kesalahan umum, jadi mungkin beberapa peringatan diperlukan.
Ini masih terjadi. Menambahkan --preload
ke panggilan Gunicorn memperbaiki masalah bagi saya.
Apakah bug ini masih belum diperbaiki? Saya mengamati perilaku yang tepat ini.
Gunicorn mulai seperti ini di 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
Proses pekerja terus-menerus habis dan dimulai ulang:
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 adalah aplikasi Flask trival.
Apakah masalah ini ditutup sebagai Jangan Perbaiki?
Saya juga mengalami masalah yang sama
Tetapi setelah Debugging saya dapat menemukan bahwa ketika gunicorn memulai Aplikasi Django salah satu ketergantungan memakan waktu lebih lama dari waktu yang diharapkan, (Dalam kasus saya koneksi DB eksternal) yang membuat gunicron
worker menjadi timeout
Ketika saya menyelesaikan masalah koneksi, masalah batas waktu juga teratasi ...
Ini bukan kasus saya. Saya menguji dengan jenis aplikasi "Halo, Dunia", tanpa ketergantungan. Jadi saya masih bingung dengan ini, tetapi sepertinya tidak mungkin untuk memiliki Gunicorn dengan utas yang berjalan lama. Proses pekerja dimulai ulang dan karenanya mematikan utas yang berjalan lama.
@leonbrag
Ini mungkin BUKAN bug gunicorn. Lihat komentar saya di atas di utas. Ini adalah efek samping dari browser yang mengirimkan koneksi TCP "diprediksi" kosong, dan menjalankan gunicorn hanya dengan beberapa pekerja sinkronisasi tanpa perlindungan dari koneksi TCP yang kosong.
Apakah ada arsitektur/desain referensi yang menunjukkan cara yang tepat untuk menyiapkan aplikasi labu Gunicorn dengan utas pekerja (permanen) yang panjang?
Jika ini bukan bug, maka ini tampaknya merupakan artefak atau batasan arsitektur/desain Gunicorn.
Mengapa pekerja sinkronisasi tidak berjalan selamanya dan menerima koneksi klien. Pekerja tersebut akan menutup soket sesuai kebutuhan, namun terus berjalan tanpa keluar (dan karenanya utas pekerja terus berjalan).
@leonbrag
Anda harus lebih spesifik tentang masalah apa yang ingin Anda pecahkan.
Masalah yang dibahas di utas ini terjadi di lingkungan pengembang dan solusi termudah adalah menambahkan lebih banyak pekerja sinkronisasi atau menggunakan pekerja berulir.
Jika Anda ingin menghindari masalah ini dalam penyiapan produksi, Anda dapat menggunakan pekerja gevent, atau Anda dapat meletakkan nginx di depan gunicorn.
Beberapa PaaS sudah meletakkan nginx di depan wadah buruh pelabuhan Anda, jadi Anda tidak perlu mengkhawatirkannya. Sekali lagi solusinya tergantung pada konteks dan detailnya.
Ini adalah bacaan yang bagus.
https://www.brianstorti.com/the-role-of-a-reverse-proxy-to-protect-your-application-against-slow-clients/
Anda dapat memeriksa halaman desain dari dokumentasi. Pekerja async adalah satu
cara untuk menjalankan tugas yang panjang.
Pada Sabtu 8 Agustus 2020 pukul 18:00 leonbrag [email protected] menulis:
Apakah ada arsitektur/desain referensi yang menunjukkan cara yang tepat untuk menyiapkan?
Aplikasi labu Gunicorn dengan utas pekerja (permanen) yang panjang?Jika ini bukan bug, maka sepertinya itu adalah artefak atau batasan dari
Arsitektur/desain Gunicorn.Mengapa pekerja sinkronisasi tidak berjalan selamanya dan menerima koneksi klien. Seperti
pekerja akan menutup soket sesuai kebutuhan, namun terus berjalan tanpa keluar
(dan karenanya utas pekerja terus berjalan).—
Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/benoitc/gunicorn/issues/1801#issuecomment-670944797 ,
atau berhenti berlangganan
https://github.com/notifications/unsubscribe-auth/AAADRIWRQGIP3R5PMVJ5ENTR7VZA3ANCNFSM4FDLD5PA
.>
Dikirim dari Ponsel saya
web: gunicorn --workers=3 app:app --timeout 200 --log-file -
Saya memperbaiki masalah saya dengan meningkatkan --timeout
Lihat juga #1388 untuk masalah tmpfs terkait Docker.
Oh, terima kasih banyak Randall, saya lupa menambahkan --worker-tmp-dir /dev/shm
ke argumen gunicorn ketika saya menjalankan gunicorn di Docker.
BTW apakah 64 Mb cukup untuk cache gunicorn?
Aneh, saya menambahkan --worker-tmp-dir /dev/shm
tetapi masih menerima:
[2020-11-27 21:01:42 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:17)
Untuk memastikan /dev/shm
adalah ramf, saya membandingkannya:
Param berikutnya:
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: Saya menggunakan PyPy
@attajutt timeout bagus tetapi Anda mempertaruhkan bahwa proses master gunicorn akan mendeteksi hangup dalam proses pekerja Anda hanya setelah 1000 detik, dan Anda akan kehilangan banyak permintaan. Juga akan sulit untuk mendeteksinya jika hanya satu dari beberapa pekerja yang akan hangup. Saya tidak akan melakukan 1000 setidaknya.
@ivictbor terima kasih untuk lmk. 1000 adalah untuk referensi. Namun demikian, saya menjalankan aplikasi setelah dimuat Ini berjalan dengan baik.
Saya mendapatkan masalah kesalahan ini juga dan setelah beberapa kali, saya menemukan bahwa masalahnya mungkin disebabkan:
Jika Anda menerapkan aplikasi Anda di cloud seperti GAE, itu tidak akan memunculkan kesalahan petunjuk apa pun.
anda dapat mencoba memunculkan kesalahan menggunakan solusi kasus ini: https://stackoverflow.com/questions/38012797/google-app-engine-502-bad-gateway-with-nodejs
Jika mengangkat 502 gateway buruk;
mungkin akan memiliki 2 kemungkinan:
sulotion lengkap dijelaskan di sini: https://www.datadoghq.com/blog/nginx-502-bad-gateway-errors-gunicorn/
berharap dapat memperbaiki siapa pun yang mengalami kesalahan dalam [CRITICAL] WORKER TIMEOUT
Menambahkan kemungkinan lain bagi mereka yang menemukan utas ini ...
Ini juga dapat disebabkan oleh buruh pelabuhan yang memberlakukan batasan sumber daya yang terlalu rendah untuk aplikasi web Anda. Misalnya saya memiliki batasan berikut:
services:
web_app:
image: blah-blah
deploy:
resources:
limits:
cpus: "0.25"
memory: 128M
dan ini ternyata terlalu rendah untuk gunicorn
jadi saya terus-menerus mendapatkan kesalahan [CRITICAL] WORKER TIMEOUT
sampai saya menghapus batasannya.
Untuk gunicorn sumber daya ini baik-baik saja. Tapi Anda memang perlu
pesawat untuk jumlah pekerja dan sumber daya yang dibutuhkan untuk Anda
aplikasi. 128M dan 0.25cpu tampaknya sangat rendah untuk aplikasi web
ditulis dengan Python.... secara umum Anda membutuhkan setidaknya 1 inti /vcpu dan
512MB RAM sebagai minimal.
Pada Jum 26 Mar 2021 pukul 02:14, Colton Hicks @ . * > menulis:
Menambahkan kemungkinan lain bagi mereka yang menemukan utas ini ...
Ini juga dapat disebabkan oleh buruh pelabuhan yang memberlakukan batasan sumber daya yang
terlalu rendah untuk aplikasi web Anda. Misalnya saya punya yang berikut
kendala:jasa:
aplikasi website:
gambar: bla-bla
menyebarkan:
sumber daya:
batas:
CPU: "0,25"
memori: 128Mdan ini ternyata terlalu rendah untuk gunicorn jadi saya terus-menerus mendapatkan [KRITIS]
WORKER TIMEOUT kesalahan sampai saya menghapus kendala.—
Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/benoitc/gunicorn/issues/1801#issuecomment-807855647 ,
atau berhenti berlangganan
https://github.com/notifications/unsubscribe-auth/AAADRITPZB7BMA6QW7LFNVLTFPNV3ANCNFSM4FDLD5PA
.>
Dikirim dari Ponsel saya
--timeout=1000 bekerja dari saya. Masalahnya adalah mesin GCP dengan sumber daya cpu rendah. Ini berfungsi dengan baik di mesin lokal saya dengan batas waktu default.
Komentar yang paling membantu
Menggunakan gunicorn dengan gevent tidak memperbaiki bug.