Gunicorn: Batas waktu pekerja instan setelah permintaan yang berjalan lama

Dibuat pada 8 Agu 2013  ·  45Komentar  ·  Sumber: benoitc/gunicorn

Kami telah mengalami masalah yang sangat aneh yang melibatkan batas waktu permintaan dengan Gunicorn yang berjalan di depan aplikasi Django kami di Heroku.

Intinya, masalah terjadi ketika permintaan yang berjalan sangat lama dibuat ke aplikasi, menyebabkannya terputus oleh batas waktu permintaan level platform Heroku setelah 30 detik. Ini sendiri bukan masalahnya - permintaan yang sudah berjalan lama seperti itu seharusnya sudah waktunya. Masalah sebenarnya terjadi pada permintaan berikutnya. Tampaknya ada kemungkinan bahwa permintaan yang terjadi _setelah_ permintaan yang sudah berjalan lama ini akan langsung memunculkan kesalahan Gunicorn dari formulir:

[CRITICAL] WORKER TIMEOUT (pid:15)

Ini menghasilkan halaman Kesalahan Server Internal yang langsung dikembalikan ke klien. Perilaku ini tidak konsisten - terkadang permintaan berikutnya akan berhasil, terkadang tidak. Kecurigaan saya adalah bahwa kesalahan akan terjadi jika permintaan ditangani oleh pekerja Gunicorn yang sama yang menangani permintaan yang sudah berjalan lama.

Kami menjalankan Gunicorn langsung dari Django sebagai berikut:

python app/manage.py run_gunicorn -b 0.0.0.0:$PORT -w 2 -k gevent

Parameter konfigurasi lain yang relevan, seperti worker_connections dan max_requests, disetel ke defaultnya. Namun, kami telah bereksperimen dengan mengubah pengaturan ini, serta jumlah pekerja, tetapi masalah yang dijelaskan di atas terjadi di semua kasus yang kami coba. Versi Gunicorn kami saat ini adalah 0.14.6, telah dibatalkan setelah kami meningkatkan ke 17.5 jika itu adalah sumber masalahnya. Sayangnya perilaku yang sama terjadi pada kedua versi.

Kami mengalami kesulitan besar untuk memahami akar penyebab masalah ini. Dari dokumentasi Heroku yang ditautkan di atas:

Sementara router telah mengembalikan respons ke klien, aplikasi Anda tidak akan mengetahui bahwa permintaan yang sedang diproses telah mencapai batas waktu, dan aplikasi Anda akan terus bekerja pada permintaan tersebut.

Saya berasumsi ini berarti bahwa terlepas dari kenyataan bahwa permintaan yang berjalan lama telah habis dari sudut pandang klien, seorang pekerja Gunicorn masih memproses permintaan tersebut. Yang membuat saya bingung adalah bagaimana ini akan menyebabkan permintaan baru berikutnya untuk langsung membuang batas waktu pekerja, mengingat pekerja menggunakan gevent dan dengan demikian utas asinkron untuk menangani permintaan. Saya akan berpikir bahwa permintaan pertama yang sudah berjalan lama adalah

  1. non-pemblokiran karena fakta bahwa ada beberapa utas gevent pekerja, dan
  2. dibunuh oleh Gunicorn sebelum permintaan berikutnya terjadi, karena batas waktu permintaan default untuk Gunicorn adalah 30 detik - identik dengan batas waktu permintaan Heroku sendiri.

Mungkin perlu disebutkan bahwa permintaan yang berjalan lama terhubung ke database PostgreSQL kami dan melakukan beberapa kueri kompleks. Kerusakan tampaknya hanya terjadi setelah koneksi yang berjalan lama habis berkat Heroku saat berinteraksi dengan DB. Kami menguji ini di server pengujian kami dengan membuat dua tampilan terpisah, salah satunya mengeksekusi kueri panjang terhadap database hingga batas waktu Heroku tercapai, dan yang lainnya hanya menunggu melewati tanda 30 detik untuk menghasilkan batas waktu Heroku. Tampilan sebelumnya dapat menyebabkan waktu tunggu pekerja Gunicorn pada permintaan berikutnya, sedangkan tampilan 'tidur' tidak .

Akan luar biasa jika ada yang memiliki wawasan tentang perilaku mendasar yang menyebabkan masalah ini - informasi tambahan apa pun yang dapat saya berikan untuk membantu mendiagnosis masalah, beri tahu saya. Saya harap ini adalah cara yang benar untuk menangani masalah seperti itu dan belum pernah diangkat/ditangani sebelumnya.

( FeaturWorker - Bugs -

Semua 45 komentar

@Jwpe Laporan bug yang luar biasa.

Hal pertama yang akan saya perhatikan adalah jika Anda menggunakan driver PostgreSQL berwarna hijau. Dulu ada versi khusus yang perlu Anda gunakan dengan tambalan monyet agar ini berfungsi dengan benar. Saya tidak tahu keadaan saat ini sekarang. Tetapi batas waktu yang Anda tempelkan adalah batas waktu pekerja dan di salah satu pekerja async yang pada dasarnya bermuara pada "sebuah greenlet belum menghasilkan lebih dari $timeout detik". Mengingat Anda menggambarkan permintaan PostgreSQL yang berjalan lama, itulah tempat pertama yang saya selidiki.

@davisp Terima kasih atas respon cepatnya!

Mengikuti penunjuk Anda, saya telah melihat adaptor psycopg2 - yang kami gunakan untuk menghubungkan aplikasi Django kami ke Postgres - dan menemukan bagian dokumentasi ini yang menyatakan:

Peringatan: Koneksi Psycopg tidak aman untuk utas hijau dan tidak dapat digunakan secara bersamaan oleh utas hijau yang berbeda. Mencoba menjalankan lebih dari satu perintah sekaligus menggunakan satu kursor per thread akan menghasilkan kesalahan (atau kebuntuan pada versi sebelum 2.4.2).
Oleh karena itu, pemrogram disarankan untuk menghindari berbagi koneksi antara coroutine atau menggunakan kunci ramah perpustakaan untuk menyinkronkan koneksi bersama, misalnya untuk penyatuan.

Dengan kata lain - psycopg2 tidak menyukai benang hijau. Berdasarkan perilaku yang kami temui, saya kira ini adalah sumber kesalahan. Cara yang disarankan untuk mengatasi masalah ini, menurut dokumen psycopg, adalah dengan menggunakan perpustakaan yang memungkinkan dukungan psycopg untuk coroutine. Pustaka yang direkomendasikan adalah psycogreen .

Saya akan mencoba membuat ulang masalah di server pengujian kami menggunakan perpustakaan psycogreen, dan melihat apakah itu menyelesaikan masalah. Mudah-mudahan saya harus dapat melaporkan beberapa hasil relatif segera.

@Jwpe Itu terlihat seperti kait yang saya ingat.

@benoitc Mungkin kita harus menyebut ini di dokumen Gunicorn di suatu tempat? Tidak sepenuhnya yakin di mana tempat terbaik akan berada.

@davisp mungkin di bagian FAQ?

hmppff lupa itu sudah ada (http://docs.gunicorn.org/en/latest/faq.html) Jadi mungkin kita bisa memiliki tautan ke bagian "pemecahan masalah" dari sana. tidak yakin, tetapi kami juga dapat memindahkan di bagian tersebut informasi apa pun tentang virtualenv dan trik lainnya.

Mungkin halaman Peringatan atau "Catatan tentang Benang Hijau". Tidak super menekan.

Saya melihat perilaku yang hampir sama persis pada Heroku yang menjalankan gunicorn dengan pekerja gevent ditambah beberapa lainnya, jadi saya beralih ke pekerja sinkron, seperti yang direkomendasikan di utas ini dan pada dasarnya masih melihat masalah serius yang sama. Saya akan mendapatkan cutoff Heroku H12 30 detik dan kemudian mengulangi kesalahan H12 dan [CRITICAL] Worker Timeout sampai saya mengatur ulang seluruh dyno (kadang-kadang satu jam atau lebih kemudian atau sampai permintaan maksimum tercapai). Jadi saya menyesuaikan batas waktu gunicorn menjadi 28 detik sehingga waktu habis sebelum Heroku memotongnya. Masalah yang sama (atau sangat mirip) terjadi sekali atau dua kali sehari dan bertahan sampai proses master dimulai ulang, hanya saja kali ini dimulai dengan H13 (koneksi ditutup) karena gunicorn memotongnya. Tidak ada lonjakan lalu lintas yang signifikan selama waktu tersebut.

Ini adalah entri profil saya saat ini:

web: newrelic-admin run-program gunicorn publisher.wsgi -b 0.0.0.0:$PORT -w 4 --max-requests 1000 --timeout 28 --preload

Detail rangkaian acara:

Pertama, saya mendapatkan beberapa permintaan yang tampaknya memakan waktu sangat lama (5+ detik), kemudian permintaan gagal dengan batas waktu H12 (batas waktu pekerja memotongnya) dan beberapa permintaan lagi akan selesai, tetapi dengan waktu yang sangat lama (20 detik). Sejak saat itu adalah cutoff heroku H11 30 detik murni sampai saya me-restart dyno.

Kami menggunakan gunicorn (v 18.0) sebagai server web kami (yang menjalankan python/Django).

Kami menjalankan newrelic, yang menunjukkan waktu henti dan waktu antrian permintaan yang sangat tinggi, tetapi tidak menawarkan wawasan lain. Tidak ada lonjakan throughput atau kondisi abnormal lainnya yang dapat saya lihat di NR. Kami menggunakan papertrail untuk pemrosesan log dan untuk mengirim email kesalahan.

Oct 15 15:08:53 nutrislice-stockton heroku/router: at=info method=GET path=/marketingtools/api/slides/?format=json-p&callback=_jqjsp&_1381871332239= host=oldham.nutrislice.com fwd="74.138.24.95" dyno=web.2 connect=15ms service=216ms status=200 bytes=21 Oct 15 15:08:54 nutrislice-stockton heroku/router: at=info method=GET path=/menu/api/menutypes/?format=json-p&callback=_jqjsp&_1381871332232= host=oldham.nutrislice.com fwd="74.138.24.95" dyno=web.2 connect=2ms service=90ms status=200 bytes=231 Oct 15 15:08:56 nutrislice-stockton heroku/router: at=info method=GET path=/menu/api/schools/?format=json-p&callback=_jqjsp&_1381871323514= host=oldham.nutrislice.com fwd="74.138.24.95" dyno=web.2 connect=3ms service=94ms status=200 bytes=5986 Oct 15 15:09:03 nutrislice-stockton heroku/router: at=info method=HEAD path=/heartbeat/ host=stockton.nutrislice.com fwd="54.247.188.179" dyno=web.2 connect=3ms service=23ms status=200 bytes=0 Oct 15 15:09:13 nutrislice-stockton heroku/router: at=info method=GET path=/menu/api/settings/?format=json-p&callback=_jqjsp&_1381871237946= host=pcsb.nutrislice.com fwd="66.87.110.127" dyno=web.2 connect=5ms service=166ms status=200 bytes=468 Oct 15 15:09:20 nutrislice-stockton heroku/router: at=info method=GET path=/menu/api/settings/?format=json-p&callback=_jqjsp&_1381871323611= host=oldham.nutrislice.com fwd="74.138.24.95" dyno=web.2 connect=6ms service=183ms status=200 bytes=453 Oct 15 15:09:40 nutrislice-stockton heroku/router: at=info method=GET path=/ host=nps.nutrislice.com fwd="74.190.240.28" dyno=web.2 connect=1ms service=260ms status=200 bytes=35951 Oct 15 15:09:55 nutrislice-stockton heroku/router: at=info method=GET path=/menuwidgets/api/list/school-menu-profile/87/menu-type/43/?format=json-p&callback=jQuery18008709754704032093_1381871379465&_=1381871393589 host=nps.nutrislice.com fwd="74.190.240.28" dyno=web.2 connect=15ms service=129ms status=200 bytes=400 Oct 15 15:09:55 nutrislice-stockton heroku/router: at=info method=GET path=/menuwidgets/api/list/school-menu-profile/306/menu-type/187/?format=json-p&callback=jQuery180013075259909965098_1381873891397&_=1381873896600 host=sdhc.nutrislice.com fwd="72.186.96.121" dyno=web.2 connect=2ms service=33ms status=200 bytes=486 Oct 15 15:10:00 nutrislice-stockton heroku/router: at=info method=GET path=/menuwidgets/186/?smp=257 host=coppellisd.nutrislice.com fwd="76.199.114.157" dyno=web.2 connect=7ms service=103ms status=200 bytes=323 Oct 15 15:10:00 nutrislice-stockton app/web.2: INFO http://stockton.nutrislice.com/heartbeat/ Pinged from IP: 10.190.159.205 -- AGENT: NewRelicPinger/1.0 (269661) Oct 15 15:10:00 nutrislice-stockton heroku/router: at=info method=HEAD path=/heartbeat/ host=stockton.nutrislice.com fwd="50.112.95.211" dyno=web.2 connect=1ms service=10ms status=200 bytes=0 Oct 15 15:10:09 nutrislice-stockton heroku/router: at=info method=GET path=/menuwidgets/239/?smp=341 host=edenpr.nutrislice.com fwd="75.73.177.139" dyno=web.2 connect=8ms service=334ms status=200 bytes=277 Oct 15 15:10:16 nutrislice-stockton heroku/router: at=info method=GET path=/menuwidgets/395/?smp=306 host=sdhc.nutrislice.com fwd="72.186.96.121" dyno=web.2 connect=1ms service=96ms status=200 bytes=245 Oct 15 15:10:20 nutrislice-stockton heroku/router: at=info method=GET path=/menuwidgets/391/?smp=305 host=sdhc.nutrislice.com fwd="173.170.34.126" dyno=web.2 connect=32ms service=5207ms status=200 bytes=290 Oct 15 15:10:22 nutrislice-stockton heroku/router: at=info method=GET path=/menuwidgets/350/?smp=305 host=sdhc.nutrislice.com fwd="173.170.34.126" dyno=web.2 connect=60ms service=7676ms status=200 bytes=1147 Oct 15 15:10:31 nutrislice-stockton heroku/router: at=info method=GET path=/menuwidgets/258/?smp=341 host=edenpr.nutrislice.com fwd="75.73.177.139" dyno=web.2 connect=42ms service=517ms status=200 bytes=26974 Oct 15 15:10:43 nutrislice-stockton heroku/router: at=info method=GET path=/menu/api/schools/?format=json-p&callback=_jqjsp&_1381871432885= host=ocps.nutrislice.com fwd="71.47.21.97" dyno=web.2 connect=1490ms service=9883ms status=200 bytes=1565 Oct 15 15:10:52 nutrislice-stockton heroku/router: at=error code=H13 desc="Connection closed without response" method=GET path=/ host=jordandistrict.nutrislice.com fwd="71.199.48.37" dyno=web.2 connect=1959ms service=29230ms status=503 bytes=0 Oct 15 15:10:52 nutrislice-stockton app/web.2: 2013-10-15 21:10:50 [2] [CRITICAL] WORKER TIMEOUT (pid:12) Oct 15 15:10:52 nutrislice-stockton app/web.2: 2013-10-15 21:10:50 [2] [CRITICAL] WORKER TIMEOUT (pid:12) Oct 15 15:10:52 nutrislice-stockton app/web.2: 2013-10-15 21:10:50 [26] [INFO] Booting worker with pid: 26 Oct 15 15:10:52 nutrislice-stockton app/web.2: 2013-10-15 21:10:50,930 (26/MainThread) newrelic.core.agent INFO - New Relic Python Agent (2.0.0.1) Oct 15 15:10:54 nutrislice-stockton heroku/router: at=info method=GET path=/surveys/api/activesurveycount/?format=json-p&callback=_jqjsp&_1381871433429= host=henrico.nutrislice.com fwd="96.248.5.53" dyno=web.2 connect=1181ms service=20074ms status=200 bytes=32 Oct 15 15:10:55 nutrislice-stockton heroku/router: at=info method=GET path=/menu/api/schooltypes/?format=json-p&callback=_jqjsp&_1381871433374= host=henrico.nutrislice.com fwd="96.248.5.53" dyno=web.2 connect=1136ms service=20393ms status=200 bytes=142 Oct 15 15:11:01 nutrislice-stockton app/web.2: using heroku production settings Oct 15 15:11:01 nutrislice-stockton app/web.2: WARNING /app/.heroku/python/lib/python2.7/site-packages/django/utils/hashcompat.py:9: DeprecationWarning: django.utils.hashcompat is deprecated; use hashlib instead Oct 15 15:11:01 nutrislice-stockton app/web.2: DeprecationWarning) Oct 15 15:11:01 nutrislice-stockton heroku/router: at=info method=GET path=/menu/api/settings/?format=json-p&callback=_jqjsp&_1381871432922= host=ocps.nutrislice.com fwd="71.47.21.97" dyno=web.2 connect=1435ms service=23198ms status=200 bytes=486 Oct 15 15:11:03 nutrislice-stockton app/web.2: WARNING /app/.heroku/python/lib/python2.7/site-packages/django/conf/urls/defaults.py:3: DeprecationWarning: django.conf.urls.defaults is deprecated; use django.conf.urls instead Oct 15 15:11:03 nutrislice-stockton app/web.2: DeprecationWarning) Oct 15 15:11:05 nutrislice-stockton heroku/router: at=info method=GET path=/menu/api/schooltypes/?format=json-p&callback=_jqjsp&_1381871443300= host=martinschools.nutrislice.com fwd="99.114.229.202" dyno=web.2 connect=1089ms service=20040ms status=200 bytes=268 Oct 15 15:11:10 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/menu/api/weeks/school-menu-profile/135/menu-type/63/2013/10/14/?format=json-p&callback=_jqjsp&_1381871439548= host=henrico.nutrislice.com fwd="96.248.5.53" dyno=web.2 connect=1018ms service=30001ms status=503 bytes=0 Oct 15 15:11:15 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/menu/api/sales/?format=json-p&callback=_jqjsp&_1381871443267= host=martinschools.nutrislice.com fwd="99.114.229.202" dyno=web.2 connect=1096ms service=30001ms status=503 bytes=0 Oct 15 15:11:15 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/menu/api/schools/?format=json-p&callback=_jqjsp&_1381871443296= host=martinschools.nutrislice.com fwd="99.114.229.202" dyno=web.2 connect=1108ms service=30000ms status=503 bytes=0 Oct 15 15:11:23 nutrislice-stockton heroku/router: at=info method=GET path=/menu/api/weeks/school-menu-profile/48/menu-type/21/2013/10/14/?format=json-p&callback=_jqjsp&_1381871449451= host=martinschools.nutrislice.com fwd="99.114.229.202" dyno=web.2 connect=1114ms service=31756ms status=200 bytes=48771 Oct 15 15:11:26 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/menu/api/sales/?format=json-p&callback=_jqjsp&_1381871455129= host=pcsb.nutrislice.com fwd="66.87.110.127" dyno=web.2 connect=990ms service=30001ms status=503 bytes=0 Oct 15 15:11:26 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/menu/api/schools/?format=json-p&callback=_jqjsp&_1381871455291= host=pcsb.nutrislice.com fwd="66.87.110.127" dyno=web.2 connect=1028ms service=30008ms status=503 bytes=0 Oct 15 15:11:31 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/menuwidgets/179/?smp=6 host=cusdnutrition.nutrislice.com fwd="68.99.246.16" dyno=web.2 connect=2492ms service=30000ms status=503 bytes=0 Oct 15 15:11:32 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/menuwidgets/192/?smp=6 host=cusdnutrition.nutrislice.com fwd="68.99.246.16" dyno=web.2 connect=2713ms service=30003ms status=503 bytes=0 Oct 15 15:11:39 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/menu/ host=hebisd.nutrislice.com fwd="38.107.226.1" dyno=web.2 connect=2115ms service=30001ms status=503 bytes=0 Oct 15 15:11:45 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/menu/api/weeks/school-menu-profile/44/menu-type/19/2013/10/14/?format=json-p&callback=_jqjsp&_1381871472583= host=pcsb.nutrislice.com fwd="66.87.110.127" dyno=web.2 connect=2168ms service=30000ms status=503 bytes=0 Oct 15 15:11:48 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/marketingtools/api/active-announcements/?format=json-p&callback=_jqjsp&_1381871476287= host=sdhc.nutrislice.com fwd="65.34.72.116" dyno=web.2 connect=1927ms service=30000ms status=503 bytes=0 Oct 15 15:11:48 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/surveys/api/activesurveycount/?format=json-p&callback=_jqjsp&_1381871476543= host=sdhc.nutrislice.com fwd="65.34.72.116" dyno=web.2 connect=2117ms service=30000ms status=503 bytes=0 Oct 15 15:11:48 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/menu/api/schooltypes/?format=json-p&callback=_jqjsp&_1381871476481= host=sdhc.nutrislice.com fwd="65.34.72.116" dyno=web.2 connect=2111ms service=30009ms status=503 bytes=0 Oct 15 15:11:50 nutrislice-stockton app/web.2: 2013-10-15 15:11:32,597 (26/NR-Activate-Session/nutrislice-stockton) newrelic.core.data_collector INFO - Successfully registered New Relic Python agent where app_name='nutrislice-stockton', pid=26, redirect_host='collector-2.newrelic.com' and agent_run_id=474482914, in 40.26 seconds. Oct 15 15:11:50 nutrislice-stockton app/web.2: INFO Successfully registered New Relic Python agent where app_name='nutrislice-stockton', pid=26, redirect_host='collector-2.newrelic.com' and agent_run_id=474482914, in 40.26 seconds. Oct 15 15:11:52 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/marketingtools/api/active-announcements/?format=json-p&callback=_jqjsp&_1381871480294= host=sdhc.nutrislice.com fwd="65.34.72.116" dyno=web.2 connect=1689ms service=30006ms status=503 bytes=0 Oct 15 15:11:55 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/menu/api/settings/?format=json-p&callback=_jqjsp&_1381871482566= host=henrico.nutrislice.com fwd="72.84.233.45" dyno=web.2 connect=2067ms service=30004ms status=503 bytes=0 Oct 15 15:11:57 nutrislice-stockton app/web.2: 2013-10-15 21:11:41 [2] [CRITICAL] WORKER TIMEOUT (pid:26) Oct 15 15:11:57 nutrislice-stockton app/web.2: 2013-10-15 21:11:41 [2] [CRITICAL] WORKER TIMEOUT (pid:26) Oct 15 15:11:57 nutrislice-stockton app/web.2: 2013-10-15 21:11:41 [29] [INFO] Booting worker with pid: 29 Oct 15 15:11:57 nutrislice-stockton app/web.2: 2013-10-15 21:11:41,067 (29/MainThread) newrelic.core.agent INFO - New Relic Python Agent (2.0.0.1) Oct 15 15:11:57 nutrislice-stockton app/web.2: using heroku production settings Oct 15 15:11:57 nutrislice-stockton app/web.2: WARNING /app/.heroku/python/lib/python2.7/site-packages/django/utils/hashcompat.py:9: DeprecationWarning: django.utils.hashcompat is deprecated; use hashlib instead Oct 15 15:11:57 nutrislice-stockton app/web.2: DeprecationWarning) Oct 15 15:11:57 nutrislice-stockton app/web.2: 2013-10-15 21:11:44 [2] [CRITICAL] WORKER TIMEOUT (pid:23) Oct 15 15:11:57 nutrislice-stockton app/web.2: 2013-10-15 21:11:44 [2] [CRITICAL] WORKER TIMEOUT (pid:23) Oct 15 15:11:57 nutrislice-stockton app/web.2: 2013-10-15 21:11:44 [32] [INFO] Booting worker with pid: 32 Oct 15 15:11:57 nutrislice-stockton app/web.2: 2013-10-15 21:11:44,154 (32/MainThread) newrelic.core.agent INFO - New Relic Python Agent (2.0.0.1) Oct 15 15:11:57 nutrislice-stockton app/web.2: using heroku production settings Oct 15 15:11:57 nutrislice-stockton app/web.2: WARNING /app/.heroku/python/lib/python2.7/site-packages/django/utils/hashcompat.py:9: DeprecationWarning: django.utils.hashcompat is deprecated; use hashlib instead Oct 15 15:11:57 nutrislice-stockton app/web.2: DeprecationWarning) Oct 15 15:11:57 nutrislice-stockton app/web.2: 2013-10-15 21:11:48 [2] [CRITICAL] WORKER TIMEOUT (pid:14) Oct 15 15:11:57 nutrislice-stockton app/web.2: 2013-10-15 21:11:48 [2] [CRITICAL] WORKER TIMEOUT (pid:14) Oct 15 15:11:57 nutrislice-stockton app/web.2: 2013-10-15 21:11:48 [35] [INFO] Booting worker with pid: 35 Oct 15 15:11:57 nutrislice-stockton app/web.2: 2013-10-15 21:11:48,273 (35/MainThread) newrelic.core.agent INFO - New Relic Python Agent (2.0.0.1) Oct 15 15:11:57 nutrislice-stockton app/web.2: using heroku production settings Oct 15 15:11:57 nutrislice-stockton app/web.2: WARNING /app/.heroku/python/lib/python2.7/site-packages/django/utils/hashcompat.py:9: DeprecationWarning: django.utils.hashcompat is deprecated; use hashlib instead Oct 15 15:11:57 nutrislice-stockton app/web.2: DeprecationWarning) Oct 15 15:11:57 nutrislice-stockton heroku/router: at=info method=GET path=/menuwidgets/353/?smp=306 host=sdhc.nutrislice.com fwd="72.186.96.121" dyno=web.2 connect=21ms service=76ms status=200 bytes=255 Oct 15 15:12:00 nutrislice-stockton app/web.2: 2013-10-15 21:11:54 [2] [CRITICAL] WORKER TIMEOUT (pid:13) Oct 15 15:12:00 nutrislice-stockton app/web.2: 2013-10-15 21:11:54 [2] [CRITICAL] WORKER TIMEOUT (pid:13) Oct 15 15:12:00 nutrislice-stockton app/web.2: 2013-10-15 21:11:54 [38] [INFO] Booting worker with pid: 38 Oct 15 15:12:00 nutrislice-stockton app/web.2: 2013-10-15 21:11:54,388 (38/MainThread) newrelic.core.agent INFO - New Relic Python Agent (2.0.0.1) Oct 15 15:12:00 nutrislice-stockton app/web.2: using heroku production settings Oct 15 15:12:01 nutrislice-stockton app/web.2: WARNING /app/.heroku/python/lib/python2.7/site-packages/django/utils/hashcompat.py:9: DeprecationWarning: django.utils.hashcompat is deprecated; use hashlib instead Oct 15 15:12:01 nutrislice-stockton app/web.2: DeprecationWarning) Oct 15 15:12:02 nutrislice-stockton app/web.2: WARNING /app/.heroku/python/lib/python2.7/site-packages/django/conf/urls/defaults.py:3: DeprecationWarning: django.conf.urls.defaults is deprecated; use django.conf.urls instead Oct 15 15:12:02 nutrislice-stockton app/web.2: DeprecationWarning) Oct 15 15:12:03 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/menuwidgets/353/?smp=306 host=sdhc.nutrislice.com fwd="108.9.154.78" dyno=web.2 connect=3650ms service=30006ms status=503 bytes=0 Oct 15 15:12:03 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/menuwidgets/395/?smp=306 host=sdhc.nutrislice.com fwd="108.9.154.78" dyno=web.2 connect=3581ms service=30006ms status=503 bytes=0 Oct 15 15:12:06 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/menu/api/settings/?format=json-p&callback=_jqjsp&_1381871492466= host=canyonsdistrict.nutrislice.com fwd="174.52.155.49" dyno=web.2 connect=3582ms service=30001ms status=503 bytes=0 Oct 15 15:12:09 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/mobile/api_version/?deviceType=iphone host=pasco.nutrislice.com fwd="173.65.148.9" dyno=web.2 connect=3837ms service=30004ms status=503 bytes=0 Oct 15 15:12:11 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/mobile/api_version/?deviceType=iphone host=canyonsdistrict.nutrislice.com fwd="174.52.155.49" dyno=web.2 connect=3987ms service=30001ms status=503 bytes=0 Oct 15 15:12:11 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/menu/api/schools/?format=json-p&callback=_jqjsp&_1381871497105= host=canyonsdistrict.nutrislice.com fwd="174.52.155.49" dyno=web.2 connect=3962ms service=30001ms status=503 bytes=0 Oct 15 15:12:11 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/menu/api/menutypes/?format=json-p&callback=_jqjsp&_1381871497128= host=canyonsdistrict.nutrislice.com fwd="174.52.155.49" dyno=web.2 connect=4020ms service=30007ms status=503 bytes=0
Dan "spiral kematian" dari H12 Time-out dan [CRITICAL] WORKER TIMEOUT ini terus berlanjut sampai proses master dimulai kembali.

Adakah ide jika ini masalah yang sama atau berbeda? Ada saran untuk diperbaiki? Saya akan berpikir bahwa karena gunicorn mematikan proses pekerja setelah mereka kehabisan waktu dan memulainya dengan segar, mereka dapat mulai memproses hal-hal secara normal, tetapi sepertinya permintaan bahkan tidak sampai ke mereka setelah itu. Mungkin ini masalah Heroku.

:+1: Juga melihat masalah ini.

Saya juga melihat masalah ini di Heroku

@sprynmr @richardkeen dapatkah Anda membagikan cara Anda meluncurkan gunicorn dan log apa pun yang Anda bisa? Ini akan banyak membantu untuk memperbaiki masalah.

@nebstrebor bagaimana jika Anda tidak membatasi jumlah permintaan?

Kami meluncurkannya seperti ini:
web: newrelic-admin run-program python manage.py run_gunicorn -b "0.0.0.0:$PORT" --log-level=DEBUG -w 3 -k gevent --max-requests 250

Bahkan dengan DEBUG tingkat log, kami tidak mendapatkan banyak informasi tentang apa yang terjadi. Tidak menggunakan gevent telah memecahkan masalah bagi kami untuk saat ini, tetapi itu tidak ideal.

@sprynmr bagaimana jika Anda menghapus jumlah maksimum permintaan? Juga versi gevent yang mana?

Kami berada di 1.0rc2 . Tidak yakin tentang jumlah permintaan maksimum. Tidak benar-benar ingin mengaktifkannya kembali untuk lingkungan produksi kami sekarang.

Membaca halaman Heroku pada batas waktu permintaan, mereka menyarankan untuk mengatur batas waktu aplikasi well under 30 seconds, such as 10 or 15 . Apakah Anda mencoba saran menggunakan parameter batas waktu di gunicorn?

Bagaimanapun masalah yang muncul dengan gevent mungkin karena cara koneksi ditangani. Versi pekerja saat ini sedang menelurkan greenlet / koneksi yang diterima tanpa pengawasan nyata dari greenlet ini. Apa yang mungkin terjadi adalah bahwa salah satu soket yang diterima akan menunggu lama, dan tidak ada peristiwa lain yang ditangani, membuat pekerja gunicorn memulai kembali. Tapi aku harus memeriksa..

Menarik. Tidak, kami tidak mencobanya.

:+1: Saya juga melihat ini di aplikasi saya. @Jwpe / @sprynmr apakah Anda pernah mendapatkan resolusi untuk masalah ini? Sepertinya sudah lebih dari 2 bulan sejak aktivitas apa pun terjadi pada masalah ini. Saya ingin mendengar jika Anda menemukan sesuatu untuk mengatasi masalah ini.

Terima kasih!

@dencold apakah Anda mencoba https://github.com/benoitc/gunicorn/issues/588#issuecomment -29267541

Saya tidak punya akun di heroku jadi tidak yakin apa fungsinya. Juga apakah Anda memiliki log yang sama?

Hai @benoitc , terima kasih banyak atas tanggapan cepatnya. Lognya persis sama dengan yang dilaporkan @Jwpe dan

Saya akan mengambil saran Anda dari komentar Anda sebelumnya dan mengonfigurasi batas waktu gunicorn menjadi lebih rendah dari batas waktu router heroku dan melihat apakah itu membantu. Terima kasih untuk sarannya.

Akan sangat membantu untuk mengetahui penyebab sebenarnya dari kegagalan cascading ini. Sungguh aneh melihat satu pekerja gagal dan kemudian seluruh server gunicorn menjadi benar-benar tidak responsif. Beri tahu saya jika ada yang bisa saya lakukan untuk membantu mendiagnosis. Saya tidak dapat mereproduksi batas waktu ini secara lokal. Tampaknya hanya terjadi pada infrastruktur heroku.

Maaf @dencold saya tidak pernah menemukan solusi. Tampaknya serangga misterius yang sangat dalam, dan saya tidak punya waktu untuk melawannya. Akan penasaran untuk melihat apakah sedikit batas waktu membantu Anda. Laporkan kembali.

@dencold apakah Anda juga menggunakan relik baru?

@benoitc ya, kami juga menggunakan relik baru.

@dencold juga, kami tidak pernah berhasil menyelesaikan masalah ini. Kami tidak punya waktu untuk berinvestasi dalam mencari tahu apa yang menyebabkan kesalahan, dan perlu fokus pada pengurangan durasi permintaan asli. Namun, sifat kritis dari kesalahan - karena itu menghadap pengguna - membuat kami beralih server WSGI untuk menghindari masalah sementara. Oleh karena itu, kami belum menjalankan eksperimen lebih lanjut untuk mengkategorikan masalah lebih lanjut.

@Jwpe apakah Anda setidaknya mencoba solusi yang diusulkan? Juga hasilnya aneh dan saya tidak pernah mereproduksinya dengan gunicorn dengan sendirinya.

Saya memiliki batas waktu hingga 15 detik dan masih melihat masalahnya

Pada hari Minggu, 26 Januari 2014, Benoit Chesneau [email protected]
menulis:

@Jwpe https://github.com/Jwpe apakah Anda setidaknya mencoba yang diusulkan
larutan? Juga hasilnya aneh dan saya tidak pernah mereproduksinya dengan gunicorn
dengan sendirinya.


Balas email ini secara langsung atau lihat di Gi tHubhttps://github.com/benoitc/gunicorn/issues/588#issuecomment -33316333
.

Ben Roberts
CTO
Nutrislice, Inc.
866-524-3444 ext 702
[email protected]

@Jwpe / @nebstrebor terima kasih banyak telah kembali

@benoitc kami telah menerapkan solusi batas waktu yang diusulkan pada instance heroku kami. Saya akan terus mengawasi ini selama beberapa hari mendatang. Akan memposting kembali jika saya melihat masalah yang sama muncul setelah batas waktu baru diberlakukan.

Terima kasih sekali lagi untuk semua orang atas bantuannya. Senang mengetahui bahwa saya bukan satu-satunya yang mengalami masalah ini. Semoga kita bisa sampai ke dasar penyebabnya.

@benoitc hanya ingin melaporkan bahwa sudah sekitar dua minggu dengan batas waktu yang lebih rendah. Kami telah melihat beberapa timeout pekerja, tetapi tidak ada yang menyebabkan seluruh proses gunicorn menjadi tidak responsif. Ini tampaknya menyelesaikan masalah, tetapi saya masih tidak yakin mengapa batas waktu 30-an menyebabkan kesalahan cascading sejak awal.

Hanya ingin membuat Anda diposting. Terima kasih lagi untuk semua bantuan di sini!

Memiliki kesalahan [CRITICAL] WORKER TIMEOUT yang sama menjalankan Django dengan gunicorn di Raspberry PI.

Tidak ada kabar.

Saya mendapatkan WAKTU PEKERJA [KRITIS] yang sama.
Masalahnya adalah bahwa setelah batas waktu nyata pekerja (permintaan lama) gunicorn membunuh pekerja dan mencoba menelurkan yang baru, tetapi pekerja baru tidak dapat memulai dalam batas TIMEOUT dan tidak mencapai tempat di mana ia menginformasikan kepada proses induk bahwa itu adalah hidup, jadi gunicorn membunuhnya lagi dan lagi :(. Dalam kasus kami masalah ini terkait dengan Gevent dan Sentry(https://github.com/getsentry/raven-python/issues/305). Sentry hanya hang saat startup .
BTW Akan sangat membantu untuk memiliki batas waktu terpisah untuk waktu mulai pekerja dan beberapa log tambahan dalam pekerja yang tidak dapat dimulai dalam waktu "batas waktu".

Batas waktu bukanlah batas waktu permintaan kecuali pada pekerja sinkronisasi. Para pekerja lainnya masih berdebar-debar kepada arbiter bahkan ketika menangani permintaan yang panjang. Timeout time adalah waktu timeout startup dalam kasus tersebut.

Dalam arti tertentu, tidak ada "batas waktu permintaan" di gunicorn.

ya, batas waktu pekerja berbeda dari batas waktu permintaan di async. Tetapi permintaan yang berjalan lama tanpa panggilan fungsi apa pun di mana "pengalihan konteks" async dapat terjadi (seperti "soket - baca/tulis") adalah penyebab batas waktu pekerja. Dan selain itu bisa ada batas waktu pada startup pekerja (di mana tidak ada permintaan sama sekali). Tetapi di log Gunicorn tidak ada cara untuk membedakan 2 kasus yang berbeda itu, hanya ada satu pesan "TIMEOUT WORKER".

Haruskah kita menambahkan pengaturan batas waktu permintaan? Itu akan membuat aplikasi dengan startup yang lama menabrak batas waktu pekerja.

Jangan berpikir begitu, karena
1) Mengukur run-time permintaan sulit, kami tidak dapat menggunakan perbedaan waktu pada saat mengemis dan pada akhir permintaan.
2) Seperti yang saya tahu, menangkap batas waktu "unit eksekusi" (jumlah kode yang berjalan di antara sakelar konteks) tidak dimungkinkan di gevent.

Ada saran kalau begitu?

Jika masalah ini hanya disebabkan oleh batas waktu yang sah dan berpotensi mengalir
batas waktu karena beban server yang tidak ada saat pertama kali dijalankan, apakah ada?
ada yang harus dilakukan di sini? Atau apakah masalah ini dapat ditutup dan ini ditangani dengan lebih baik
secara operasional pada tingkat infrastruktur yang berbeda?
Pada 30 Juli 2014 13:14, "Mkrtich" [email protected] menulis:

Jangan berpikir begitu, karena
1) Mengukur run-time permintaan sulit, kami tidak dapat menggunakan perbedaan waktu di
memohon dan di akhir permintaan.
2) Seperti yang saya tahu menangkap batas waktu "unit eksekusi" (jumlah kode
yang berjalan di antara sakelar konteks) tidak dimungkinkan di gevent.


Balas email ini secara langsung atau lihat di GitHub
https://github.com/benoitc/gunicorn/issues/588#issuecomment -50673040.

Saran adalah memiliki 2 parameter batas waktu dan 2 log yang berbeda.
1) Salah satunya adalah parameter batas waktu saat ini yang hanya akan berfungsi selama penanganan permintaan.
2) Yang kedua adalah batas waktu startup pekerja.

Juga melihat masalah ini

Kami akhirnya beralih ke uWSGI untuk Heroku dan mendapatkan kesuksesan yang lebih baik ... bukan perbaikan untuk Gunicorn, saya menyadari, tetapi saya pikir saran itu mungkin bermanfaat bagi seseorang yang melihat masalah ini di server produksi mereka dan membutuhkan resolusi lebih cepat daripada nanti .

@nebstrebor, apakah Anda mencoba saran untuk menurunkan batas waktu?

@CrazyPython tiket telah ditutup. Bisakah Anda membuka tiket baru menjelaskan masalah yang Anda miliki dan bagaimana kami dapat mereproduksinya? Pasti akan membantu untuk mengetahui apakah itu masalah yang sama, sesuatu yang lain dan rekan :)

Ya, itu tidak membuat perbedaan, seperti yang disebutkan di atas. Masalahnya sporadis
cukup (tidak pernah bisa mereproduksi) dan cukup bencana sehingga kami harus
membuat langkah itu (sudah lebih dari setahun). Saya sangat suka Gunicorn,
dan kami menggunakannya di luar Heroku tanpa masalah.

Ben Roberts
CTO & Co-founder
Nutrislice, Inc.
[email protected]
sel - 801-735-7845

Pada Selasa, 30 Jun 2015 jam 08:08, Benoit Chesneau [email protected]
menulis:

@nebstrebor https://github.com/nebstrebor baik apakah Anda mencoba
saran untuk menurunkan batas waktu?

@CrazyPython https://github.com/CrazyPython tiket telah ditutup.
Bisakah Anda membuka tiket baru menjelaskan masalah yang Anda miliki dan bagaimana kami bisa
memperbanyaknya? Pasti akan membantu untuk mengetahui apakah itu masalah yang sama,
sesuatu yang lain dan co :)


Balas email ini secara langsung atau lihat di GitHub
https://github.com/benoitc/gunicorn/issues/588#issuecomment -117199606.

Saya pikir kita juga melihat masalah ini. Kedua pekerja (--pekerja 2) terpaku pada beberapa permintaan yang berjalan lama, akhirnya terbunuh (--batas waktu 20), dan kami segera melihat dua H13, dan kemudian kami mulai memulai ulang H12 & TIMEOUT WORKER. Selama 10 menit berikutnya, ini berlanjut, para pekerja tidak pernah berhasil memproses permintaan sebelum mereka mencapai batas waktu dan memulai kembali. Jadi, kami memulai kembali dyno, dan itu memperbaikinya.

Satu hal menarik yang saya perhatikan bahwa saya tidak melihat catatan orang lain - kami melihat dua H13 (Koneksi ditutup tanpa tanggapan) di awal masalah, dan kemudian ketika kami akhirnya mengeluarkan SIGTERM, kami melihat banjir H13 - 48 tepatnya, yang merupakan jumlah TIMEOUT PEKERJA yang sama yang kami lihat (tidak termasuk dua yang pertama yang kami lihat langsung untuk H13). Saya tidak begitu yakin apa artinya, tapi sepertinya mencurigakan....

apa itu H13s atau H12s? Apakah ini sesuatu dari heroku? Bagaimana diberikan port di mana gunicorn akan diikat? Saya menduga proxy heroku tidak mendeteksi bahwa soket ditutup.

Juga pekerja mana yang Anda gunakan?

Ya, itu adalah kode kesalahan Heroku:
H12 - Batas Waktu Permintaan - biasanya 30 detik (https://devcenter.heroku.com/articles/error-codes#h12-request-timeout)
H13 - Koneksi Tertutup tanpa Respons - (https://devcenter.heroku.com/articles/error-codes#h13-connection-closed-without-response)

Sunting: Saya baru menyadari bahwa gunicorn akan menggunakan PORT jika ada sebagai variabel lingkungan, jadi begitulah cara port dikonfigurasi.

Kami menggunakan pekerja sinkron.

Dan saya juga lupa menyebutkan, kami menjalankan gunicorn 19.3.0

menutup masalah karena sudah lama tidak ada aktivitas disana. Mungkin memiliki batas waktu yang tertunda akan baik untuk aplikasi yang mulai lama tetapi itu harus dilakukan di tiket lain jika diperlukan.

Hai, saya juga menghadapi masalah yang sama dengan gunicorn uvicorn di heroku dengan procfile admin peninggalan baru:

newrelic-admin run-program gunicorn -w 4 -k uvicorn.workers.UvicornWorker app.main:fastapi_app -b 0.0.0.0:${PORT:-5000} --log-level info --access-logfile=- --logger-class=gunicorn_color.Logger --preload

Ini membawa saya ke log ini segera setelah sistem di-boot:

2021-03-19T13:18:19.187532+00:00 heroku[web.1]: State changed from starting to up
2021-03-19T13:18:51.964740+00:00 heroku[router]: at=error code=H12 desc="Request timeout" method=GET path="/" host=api-app-clienti-pr-49.herokuapp.com request_id=8742009a-3e56-4f83-a147-97ff84d4e30b fwd="5.89.111.249" dyno=web.1 connect=1ms service=30003ms status=503 bytes=0 protocol=https
2021-03-19T13:19:04.292784+00:00 heroku[router]: at=error code=H12 desc="Request timeout" method=GET path="/api" host=api-app-clienti-pr-49.herokuapp.com request_id=85b6320a-7728-4074-87eb-b0992e7c3f9d fwd="5.89.111.249" dyno=web.1 connect=3ms service=30001ms status=503 bytes=0 protocol=https
Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

joekohlsdorf picture joekohlsdorf  ·  4Komentar

zenglingyu picture zenglingyu  ·  4Komentar

twosigmajab picture twosigmajab  ·  4Komentar

benoitc picture benoitc  ·  4Komentar

thomasjungblut picture thomasjungblut  ·  3Komentar