Kesalahan batas waktu pekerja Gunicorn

182

Saya memiliki setup gunicorn dengan 3 pekerja 30 koneksi pekerja dan menggunakan kelas pekerja eventlet. Ini adalah pengaturan di belakang Nginx. Setelah setiap beberapa permintaan, saya melihat ini di log.

[ERROR] gunicorn.error: WORKER TIMEOUT (pid:23475)
None
[INFO] gunicorn.error: Booting worker with pid: 23514

Mengapa ini terjadi? Bagaimana saya bisa mengetahui apa yang salah?

Terima kasih

John
sumber
2
Anda bisa menyelesaikan masalah? Silakan bagikan pemikiran Anda karena saya juga terjebak dengan itu. Gunicorn==19.3.1dangevent==1.0.1
Black_Rider
2
Menemukan solusi untuk itu. Peningkatan batas waktu ke nilai yang sangat besar dan kemudian saya dapat melihat jejak tumpukan
Black_Rider

Jawaban:

156

Kami memiliki masalah yang sama menggunakan Django + nginx + gunicorn. Dari dokumentasi Gunicorn kami telah mengkonfigurasi timeout anggun yang membuat hampir tidak ada perbedaan.

Setelah beberapa pengujian, kami menemukan solusinya, parameter untuk mengkonfigurasi adalah: batas waktu (Dan batas waktu tidak anggun). Ini bekerja seperti jam ..

Begitu juga:

1) buka file konfigurasi gunicorn

2) atur TIMEOUT ke apa yang Anda butuhkan - nilainya dalam hitungan detik

NUM_WORKERS=3
TIMEOUT=120

exec gunicorn ${DJANGO_WSGI_MODULE}:application \
--name $NAME \
--workers $NUM_WORKERS \
--timeout $TIMEOUT \
--log-level=debug \
--bind=127.0.0.1:9000 \
--pid=$PIDFILE
Amit Talmor
sumber
9
Terima kasih ini jawaban yang tepat. Dan kemudian, untuk menghemat sumber daya dengan banyak koneksi bersamaan:, pip install geventlalu worker_class geventdi file konfigurasi Anda atau -k geventpada baris perintah.
little_birdie
2
Saya menjalankan dengan penyelia sehingga menambahkannya ke conf.d / app.conf :command=/opt/env_vars/run_with_env.sh /path/to/environment_variables /path/to/gunicorn --timeout 200 --workers 3 --bind unix:/path/to/socket server.wsgi:application
lukik
31

Di Google Cloud Cukup tambahkan --timeout 90ke titik masuk diapp.yaml

entrypoint: gunicorn -b :$PORT main:app --timeout 90
Apoorv Agarwal
sumber
21

Jalankan Gunicorn dengan --log-level=DEBUG.

Seharusnya memberi Anda jejak tumpukan aplikasi.

gwik
sumber
41
Tidak dalam kasus saya.
Joe
16
sekarang--log-level debug
psychok7
4
Saya ingin mendapatkan stracktrace, tetapi tidak ada yang bekerja di sini, menggunakan gunicorn 19.4.5. Hal-hal debug ditampilkan, jadi saya kira bendera dikenali, tetapi tidak stacktrace pada batas waktu.
orzel
6

Anda perlu menggunakan kelas tipe pekerja lain yang async seperti gevent atau tornado lihat ini untuk penjelasan lebih lanjut: Penjelasan pertama:

Anda mungkin juga ingin menginstal Eventlet atau Gevent jika Anda berharap kode aplikasi Anda mungkin perlu dijeda untuk periode waktu yang lama selama pemrosesan permintaan

Kedua :

Pekerja sinkron default menganggap bahwa aplikasi Anda terikat sumber daya dalam hal CPU dan bandwidth jaringan. Umumnya ini berarti bahwa aplikasi Anda tidak boleh melakukan apa pun yang membutuhkan waktu yang tidak ditentukan. Misalnya, permintaan ke internet memenuhi kriteria ini. Pada titik tertentu jaringan eksternal akan gagal sedemikian rupa sehingga klien akan menumpuk di server Anda.

Dseed
sumber
Bagaimana saya benar-benar memanfaatkan kelas pekerja yang begitu berbeda?
Frederick Nord
6

Saya memiliki masalah yang sangat mirip, saya juga mencoba menggunakan "runserver" untuk melihat apakah saya dapat menemukan sesuatu tetapi yang saya miliki hanyalah sebuah pesan Killed

Jadi saya pikir itu bisa menjadi masalah sumber daya, dan saya terus memberi RAM lebih banyak untuk instance, dan itu berhasil.

James Lin
sumber
1
Saya melihat masalah ini bahkan dengan gevent dan batas waktu diset dengan benar, dari memori adalah masalahnya
bcattle
6

WORKER TIMEOUTberarti aplikasi Anda tidak dapat menanggapi permintaan dalam jumlah waktu yang ditentukan. Anda dapat mengatur ini menggunakan pengaturan batas waktu gunicorn . Beberapa aplikasi memerlukan lebih banyak waktu untuk merespons daripada yang lain.

Hal lain yang mungkin mempengaruhi hal ini adalah memilih jenis pekerja

Pekerja sinkron default menganggap bahwa aplikasi Anda terikat sumber daya dalam hal CPU dan bandwidth jaringan. Umumnya ini berarti bahwa aplikasi Anda tidak boleh melakukan apa pun yang membutuhkan waktu yang tidak ditentukan. Contoh dari sesuatu yang membutuhkan jumlah waktu yang tidak ditentukan adalah permintaan ke internet. Pada titik tertentu jaringan eksternal akan gagal sedemikian rupa sehingga klien akan menumpuk di server Anda. Jadi, dalam hal ini, aplikasi web apa pun yang membuat permintaan keluar ke API akan mendapat manfaat dari pekerja yang tidak sinkron.

Ketika saya mendapat masalah yang sama dengan Anda (saya mencoba untuk menyebarkan aplikasi saya menggunakan Docker Swarm), saya telah mencoba untuk meningkatkan batas waktu dan menggunakan jenis kelas pekerja lainnya. Namun semuanya gagal.

Dan kemudian saya tiba-tiba menyadari bahwa saya membatasi sumber daya saya terlalu rendah untuk layanan di dalam file penulisan saya. Ini adalah hal memperlambat aplikasi dalam kasus saya

deploy:
  replicas: 5
  resources:
    limits:
      cpus: "0.1"
      memory: 50M
  restart_policy:
    condition: on-failure

Jadi saya sarankan Anda untuk memeriksa hal apa yang memperlambat aplikasi Anda

hashlash
sumber
4

Apakah titik akhir ini terlalu lama?

Mungkin Anda menggunakan labu tanpa dukungan sinkronisasi, sehingga setiap permintaan akan memblokir panggilan. Untuk membuat dukungan async tanpa menyulitkan, tambahkangevent pekerja.

Dengan gevent, panggilan baru akan menelurkan utas baru, dan aplikasi Anda akan dapat menerima lebih banyak permintaan

pip install gevent
gunicon .... --worker-class gevent
Ramon Medeiros
sumber
1
tweak sederhana .. menyelamatkan hari saya!
penduDev
3

Saya punya masalah yang sama di Docker.

Di Docker saya menyimpan permintaan LightGBMmodel + Flaskmelayani yang terlatih . Sebagai server HTTP yang saya gunakan gunicorn 19.9.0. Ketika saya menjalankan kode saya secara lokal pada laptop Mac saya semuanya bekerja dengan sempurna, tetapi ketika saya menjalankan aplikasi di Docker, permintaan POST JSON saya membeku selama beberapa waktu, maka gunicornpekerja telah gagal [CRITICAL] WORKER TIMEOUTkecuali.

Saya mencoba banyak pendekatan berbeda, tetapi satu-satunya yang memecahkan masalah saya adalah menambahkan worker_class=gthread.

Ini konfigurasi lengkap saya:

import multiprocessing

workers = multiprocessing.cpu_count() * 2 + 1
accesslog = "-" # STDOUT
access_log_format = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(q)s" "%(D)s"'
bind = "0.0.0.0:5000"
keepalive = 120
timeout = 120
worker_class = "gthread"
threads = 3
Artem Zaika
sumber
memutakhirkan beberapa jawaban Anda yang lain juga hanya yang ini saja tidak cukup: P
Achala Dissanayake
1

batas waktu adalah parameter kunci untuk masalah ini.

tapi itu tidak cocok untukku.

saya menemukan tidak ada kesalahan waktu habis gunicorn ketika saya mengatur pekerja = 1.

ketika saya melihat-lihat kode saya, saya menemukan beberapa soket terhubung (socket.send & socket.recv) di server init.

socket.recv akan memblokir kode saya dan itulah mengapa selalu habis ketika pekerja> 1

berharap dapat memberikan beberapa ide kepada orang-orang yang memiliki masalah dengan saya

Mao
sumber
1

Ini bekerja untuk saya:

gunicorn app:app -b :8080 --timeout 120 --workers=3 --threads=3 --worker-connections=1000

Jika Anda telah eventletmenambahkan:

--worker-class=eventlet

Jika Anda telah geventmenambahkan:

--worker-class=gevent
Skerrepy
sumber
0

Bagi saya, solusinya adalah menambahkan --timeout 90ke titik masuk saya, tetapi tidak berfungsi karena saya telah menentukan dua titik masuk, satu di app.yaml, dan satu lagi di Dockerfile saya. Saya menghapus titik masuk yang tidak digunakan dan menambahkan --timeout 90yang lain.

PV
sumber