Gunicorn: مهلات العامل الفوري بعد الطلبات طويلة الأمد

تم إنشاؤها على ٨ أغسطس ٢٠١٣  ·  45تعليقات  ·  مصدر: benoitc/gunicorn

لقد واجهنا مشكلة غريبة للغاية تتعلق بمهلة الطلبات مع تشغيل Gunicorn أمام تطبيق Django على Heroku.

في جوهرها ، تحدث المشكلة عندما يتم تقديم طلب طويل الأمد للتطبيق ، مما يؤدي إلى قطعه من خلال مهلة طلب Heroku

[CRITICAL] WORKER TIMEOUT (pid:15)

ينتج عن هذا صفحة خطأ خادم داخلي يتم إرجاعها إلى العميل على الفور. هذا السلوك غير متسق - أحيانًا ينجح الطلب التالي ، وأحيانًا لا ينجح. أشك في أن الخطأ سيحدث إذا تمت معالجة الطلب من قبل نفس عامل Gunicorn الذي كان يتعامل مع الطلب طويل الأمد.

نحن ندير Gunicorn مباشرة من Django على النحو التالي:

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

يتم تعيين معلمات التكوين الأخرى ذات الصلة ، مثل worker_connections و max_requests ، في الإعدادات الافتراضية. ومع ذلك ، فقد جربنا تغيير هذه الإعدادات ، وكذلك عدد العمال ، ولكن المشكلة الموضحة أعلاه تحدث في جميع الحالات التي حاولناها. إصدار Gunicorn الحالي الخاص بنا هو 0.14.6 ، بعد أن تراجع بعد أن قمنا بالترقية إلى 17.5 في حال كان هذا هو مصدر المشكلة. لسوء الحظ ، يحدث نفس السلوك في كلا الإصدارين.

نواجه صعوبة كبيرة في فهم السبب الجذري لهذه المشكلة. من وثائق Heroku المرتبطة أعلاه:

أثناء قيام جهاز التوجيه بإرجاع استجابة للعميل ، لن يعرف التطبيق الخاص بك أن الطلب الذي يقوم بمعالجته قد انتهى ، وسيستمر تطبيقك في العمل على الطلب.

أفترض أن هذا يعني أنه على الرغم من حقيقة أن الطلب الأصلي طويل الأمد قد انتهى من منظور العميل ، إلا أن عامل Gunicorn لا يزال يعالج الطلب. ما يحيرني هو كيف أن هذا قد يتسبب في طلب جديد لاحق لإلغاء مهلة العامل على الفور ، بالنظر إلى أن العمال يستخدمون مؤشرات ترابط gevent وبالتالي غير متزامنة للتعامل مع الطلبات. كنت أعتقد أن أول طلب طويل الأمد سيكون

  1. غير محظور نظرًا لوجود العديد من سلاسل رسائل gevent للعاملين ، و
  2. قتل بواسطة Gunicorn قبل حدوث أي طلبات لاحقة ، نظرًا لأن مهلة الطلب الافتراضية لـ Gunicorn هي 30 ثانية - وهي مطابقة لمهلة طلب Heroku الخاصة.

قد يكون من الجدير بالذكر أن الطلبات طويلة الأمد تتصل بقاعدة بيانات PostgreSQL الخاصة بنا وتقوم بالعديد من الاستعلامات المعقدة. يبدو أن الأعطال تحدث فقط بعد انقضاء مهلة الاتصال طويلة المدى بفضل Heroku أثناء التفاعل مع DB. لقد اختبرنا هذا على خادم الاختبار الخاص بنا من خلال إنشاء عرضين منفصلين ، أحدهما ينفذ استعلامات طويلة ضد قاعدة البيانات حتى يتم الوصول إلى مهلة Heroku ، والآخر ينتظر ببساطة تجاوز علامة 30 ثانية لإنتاج مهلة Heroku. كان العرض الأول قادرًا على التسبب في انقضاء مهلات عامل Gunicorn في الطلب التالي ، بينما لم يكن العرض "نائمًا" كذلك.

سيكون من الرائع أن يكون لدى أي شخص أي فكرة عن السلوك الأساسي الذي يسبب هذه المشكلة - أي معلومات إضافية يمكنني تقديمها للمساعدة في تشخيص المشكلة ، يرجى إعلامي بذلك. آمل أن تكون هذه هي الطريقة الصحيحة للتعامل مع مثل هذه المشكلة ولم يتم طرحها / معالجتها من قبل.

( FeaturWorker - Bugs -

ال 45 كومينتر

Jwpe تقرير خطأ ممتاز.

أول شيء أود النظر فيه هو إذا كنت تستخدم برنامج تشغيل PostgreSQL أخضر اللون. كان هناك إصدار محدد تحتاج إلى استخدامه مع رقعة قرد لجعل هذا يعمل بشكل صحيح. لا أعرف الوضع الحالي للأمور الآن. لكن المهلة التي قمت بلصقها هي مهلة عامل وفي أحد العمال غير المتزامنين الذي يتلخص أساسًا في "أخضر لم يسفر عن أكثر من دولار من ثواني المهلة". نظرًا لأنك تصف طلبات PostgreSQL التي طال أمدها ، فهذا هو المكان الأول الذي سأبحث فيه.

davisp شكرا على الاستجابة السريعة على هذا!

بعد المؤشر الخاص بك ، ألقيت نظرة على محول psycopg2 - الذي نستخدمه لربط تطبيق Django الخاص بنا بـ Postgres - واكتشفت هذا القسم من الوثائق التي تنص على:

تحذير: وصلات Psycopg ليست آمنة للخيوط الخضراء ولا يمكن استخدامها بشكل متزامن بواسطة خيوط خضراء مختلفة. ستؤدي محاولة تنفيذ أكثر من أمر واحد في وقت واحد باستخدام مؤشر واحد لكل مؤشر ترابط إلى حدوث خطأ (أو توقف تام في الإصدارات قبل 2.4.2).
لذلك ، يُنصح المبرمجون إما بتجنب مشاركة الاتصالات بين coroutines أو استخدام قفل مناسب للمكتبة لمزامنة الاتصالات المشتركة ، على سبيل المثال للتجميع.

بمعنى آخر - لا يحب psycopg2 الخيوط الخضراء. بناءً على السلوك الذي واجهناه ، أعتقد أن هذا هو مصدر الخطأ. الطريقة المقترحة للتعامل مع هذه المشكلة ، وفقًا لمستندات psycopg ، هي استخدام مكتبة تتيح دعم psycopg لـ coroutines. المكتبة الموصى بها هي psycogreen .

سأحاول إعادة إنشاء المشكلة على خادم الاختبار الخاص بنا باستخدام مكتبة psycogreen ، ومعرفة ما إذا كان يحل المشكلة. آمل أن أتمكن من الإبلاغ عن بعض النتائج قريبًا نسبيًا.

Jwpe هذا يشبه الخطاف الذي كنت أتذكره.

benoitc ربما يجب أن نطلق على هذا الأمر في مستندات Gunicorn في مكان ما؟ لست متأكدا تماما أين سيكون أفضل مكان بالرغم من ذلك.

davisp ربما في قسم الأسئلة الشائعة؟

hmppff forgiot كان موجودًا بالفعل (http://docs.gunicorn.org/en/latest/faq.html) لذلك ربما يمكننا الحصول على رابط لقسم "استكشاف الأخطاء وإصلاحها" من هناك. لست متأكدًا ، ولكن يمكننا أيضًا نقل أي معلومات حول virtualenv وغيرها من الحيل في هذا القسم.

ربما صفحة تحذيرات أو "ملاحظات حول الخيوط الخضراء". ليس فائق الضغط.

كنت أرى نفس السلوك تقريبًا على Heroku وهو يدير gunicorn مع عمال gevent بالإضافة إلى بعض الآخرين ، لذلك تحولت إلى عمال متزامنين ، على النحو الموصى به في هذا الموضوع وما زلت أرى نفس المشكلة الخطيرة. سأحصل على قطع Heroku H12 لمدة 30 ثانية ثم كرر أخطاء H12 و [CRITICAL] Worker Timeout حتى أقوم بإعادة تعيين dyno بالكامل (أحيانًا بعد ساعة أو أكثر أو حتى يتم الوصول إلى الحد الأقصى للطلبات). لذلك قمت بتعديل مهلة gunicorn إلى 28 ثانية حتى تنتهي المهلة قبل أن يقطعها Heroku. تحدث نفس المشكلة (أو ما شابهها جدًا) مرة أو مرتين يوميًا وتستمر حتى يتم إعادة تشغيل العملية الرئيسية ، ولكن هذه المرة فقط تبدأ بـ H13 (الاتصال مغلق) لأن gunicorn يقطعها. لم يكن هناك ارتفاع كبير في حركة المرور خلال تلك الأوقات.

هنا هو إدخال procfile الحالي الخاص بي:

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

تفاصيل سلسلة الأحداث:

أولاً ، تلقيت بعض الطلبات التي يبدو أنها تستغرق وقتًا طويلاً (أكثر من 5 ثوانٍ) ، ثم يفشل الطلب مع مهلة H12 (مهلة العامل تقطعه) وستنتهي بعض الطلبات الأخرى ، ولكن مع أوقات طويلة بشكل استثنائي (20 ثواني). من ذلك الحين فصاعدًا ، يتم قطع heroku H11 لمدة 30 ثانية حتى أقوم بإعادة تشغيل dyno.

نحن نستخدم gunicorn (الإصدار 18.0) كخادم الويب الخاص بنا (والذي يقوم بتشغيل python / django).

نقوم بتشغيل newrelic ، والتي تظهر وقت التوقف عن العمل وأوقات انتظار الطلبات المرتفعة بجنون ، ولكنها لا تقدم أي رؤية أخرى. لم تكن هناك طفرات في الإنتاجية أو غيرها من الظروف غير الطبيعية التي يمكنني رؤيتها في NR. نستخدم مسند الورق لمعالجة السجل ولإرسال رسائل البريد الإلكتروني التي تحتوي على أخطاء.

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
وتستمر هذه "دوامة الموت" لفترات H12 ومهلة العامل [الحرجة] باستمرار حتى يتم إعادة بدء العملية الرئيسية.

أي أفكار إذا كانت هذه هي نفس المشكلة أو مشكلة مختلفة؟ أي اقتراحات لإصلاح؟ أعتقد أنه نظرًا لأن gunicorn يقتل عمليات العمال بعد انقضاء مهلهم وبدء تشغيلهم جديدًا ، فسيكون بمقدورهم البدء في معالجة الأشياء بشكل طبيعي ، ولكن يبدو أن الطلبات لا تصل إليهم بعد ذلك. ربما انها قضية Heroku.

: +1: رؤية هذه المشكلة أيضًا.

أرى أيضًا هذه المشكلة على Heroku

sprynmrrichardkeen هل يمكنك مشاركة الطريقة التي تقوم بها بتشغيل برنامج Gunicorn وأي سجل يمكنك استخدامه؟ سيساعد كثيرا في حل المشكلة.

nebstrebor ماذا لو لم تحدد عدد الطلبات؟

كنا نطلقها على النحو التالي:
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

حتى مع DEBUG على مستوى السجل ، لم نواجه الكثير في طريق السجلات حول ما كان يحدث. أدى عدم استخدام gevent إلى حل المشكلة بالنسبة لنا في الوقت الحالي ، لكنها ليست مثالية.

sprynmr ماذا لو أزلت الحد الأقصى لعدد الطلبات؟ أيضا أي إصدار من gevent؟

كنا على 1.0rc2 . غير متأكد بشأن الحد الأقصى لعدد الطلبات. لا تريد حقًا إعادة تشغيله لبيئة الإنتاج لدينا الآن.

عند قراءة صفحة Heroku عند انتهاء مهلة الطلب ، يقترحون تعيين مهلة التطبيق well under 30 seconds, such as 10 or 15 . هل جربت الاقتراح باستخدام معلمة timeout في gunicorn؟

على أي حال ، فإن المشكلة التي تظهر مع gevent ربما ترجع إلى الطريقة التي يتم بها التعامل مع الاتصالات. الإصدار الحالي للعامل يفرخ Greenlet / اتصالات مقبولة دون أي إشراف حقيقي على هذا Greenlet. ما يحدث على الأرجح هو أن أحد المقبس المقبولة سينتظر لفترة طويلة ، ولا يتم التعامل مع أي أحداث أخرى ، مما يجعل العامل الجونيكورن يعيد التشغيل. لكن علي أن أتحقق ..

مثير للإعجاب. لا لم نحاول ذلك.

: +1: أرى هذا في طلبي أيضًا. Jwpe / sprynmr هل

شكرا!

dencold هل جربت https://github.com/benoitc/gunicorn/issues/588#issuecomment -29267541

ليس لدي حساب في heroku لذا لست متأكدًا مما يفعله. هل لديك نفس السجلات؟

مرحبًا benoitc ، شكرًا جزيلاً على الرد السريع. السجلات هي بالضبط نفس ما ذكرتJwpe وnebstrebor. يسعدني سحب الأجزاء ذات الصلة وإضافتها هنا إذا كان ذلك سيساعد في عزل المشكلة ، فما عليك سوى إعلامي.

سأأخذ نصيحتك من تعليقك السابق وقم بتكوين مهلة gunicorn لتكون أقل من مهلة جهاز التوجيه heroku ومعرفة ما إذا كان ذلك يساعد. شكرا على اقتراحك.

سيكون من المفيد معرفة السبب الفعلي لهذا الفشل المتتالي. من الغريب حقًا رؤية عامل واحد يفشل ثم يصبح خادم Gunicorn بأكمله غير مستجيب تمامًا. يُرجى إعلامي إذا كان هناك أي شيء يمكنني القيام به للمساعدة في التشخيص. لا يمكنني إعادة إنتاج هذه المهلة محليًا. يبدو أنه يحدث فقط في بنية heroku الأساسية.

آسف dencold لم أجد حلاً أبدًا. بدا خطأ غامضًا للغاية ، ولم يكن لدي وقت للقتال معه. سيكون فضوليًا لمعرفة ما إذا كان جزء المهلة يساعدك. تقرير مرة أخرى.

dencold هل تستخدم أيضًا بقايا جديدة؟

benoitc نعم ، نحن أيضًا نستخدم بقايا جديدة.

dencold بالمثل ، لم ننجح أبدًا في حل هذه المشكلة. لم يكن لدينا الوقت الكافي للاستثمار في اكتشاف سبب الأخطاء ، واحتجنا إلى التركيز على تقليل مدة الطلبات الأصلية. ومع ذلك ، دفعتنا الطبيعة الحرجة للخطأ - نظرًا لأنه واجه المستخدم - إلى تبديل خوادم WSGI لتجنب المشكلة في غضون ذلك. ومن ثم ، لم نقم بإجراء أي تجارب أخرى لتصنيف المشكلة بشكل أكبر.

Jwpe هل جربت الحل المقترح على الأقل؟ كما أن النتيجة غريبة وأنا لا أقوم باستنساخ ذلك باستخدام جونيكورن بمفرده.

كان لديّ وقت قطع أقل من 15 ثانية وما زلت أرى المشكلة

يوم الأحد ، 26 يناير 2014 ، Benoit Chesneau [email protected]
كتب:

Jwpe https://github.com/Jwpe هل جربت على الأقل المقترح
المحلول؟ كما أن النتيجة غريبة وأنا لا أعيد إنتاجها باستخدام البوق
بنفسها.

-
قم بالرد على هذه الرسالة الإلكترونية مباشرة أو tHubhttps: //github.com/benoitc/gunicorn/issues/588#issuecomment -33316333
.

بن روبرتس
CTO
Nutrislice، Inc.
866-524-3444 تحويلة 702
[email protected]

Jwpe / nebstrebor شكرًا جزيلاً على

benoitc قمنا بتنفيذ حل المهلة المقترح على مثيل heroku الخاص بنا. سأراقب هذا عن كثب خلال الأيام القادمة. سأعيد النشر إذا رأيت نفس المشكلة منبثقة بعد انتهاء المهلة الجديدة.

شكرا مرة أخرى للجميع على المساعدة. من الجيد معرفة أنني لست الوحيد الذي يواجه هذه المشكلة. نأمل أن نتمكن من الوصول إلى الجزء السفلي من القضية.

أراد benoitc فقط الإبلاغ عن مرور حوالي أسبوعين مع انخفاض المهلة. لقد رأينا بعض المهلات الخاصة بالعاملين ، ولكن لا شيء يتسبب في عدم استجابة العملية البعيدة بأكملها. يبدو أن هذا يحل المشكلة ، لكنني ما زلت غير متأكد من سبب تسبب مهلات الثلاثينيات في حدوث الخطأ المتتالي في المقام الأول.

أردت فقط أن تبقيك على اطلاع. شكرا مرة أخرى على كل المساعدة هنا!

وجود نفس خطأ TIMEOUT العامل [الحرج] أثناء تشغيل Django مع gunicorn في Raspberry PI.

لا أخبار.

أحصل على نفس المهلة [الحرجة] للعمال.
تكمن المشكلة في أنه بعد انتهاء المهلة الفعلية للعامل (طلب طويل) ، يقتل gunicorn العامل ويحاول إنتاج واحد جديد ، لكن العامل الجديد لا يمكنه البدء في حدود TIMEOUT ولا يصل إلى المكان الذي يبلغ فيه عملية الوالدين بأنه كذلك مباشر ، لذلك يقتلها البوق مرارًا وتكرارًا :(. في حالتنا ، كانت المشكلة متعلقة بـ Gevent و Sentry (https://github.com/getsentry/raven-python/issues/305). توقف Sentry عند بدء التشغيل .
راجع للشغل سيكون مفيدًا أن يكون لديك مهلة منفصلة لوقت بدء العامل وبعض السجلات الإضافية داخل العامل التي لا يمكن أن تبدأ خلال وقت "المهلة".

المهلة ليست مهلة طلب إلا في عامل المزامنة. لا يزال العمال الآخرون ينبضون بالحكم حتى عند التعامل مع الطلبات الطويلة. وقت انتهاء المهلة هو وقت انتهاء مهلة بدء التشغيل في هذه الحالة.

بمعنى ما ، لا يوجد "طلب مهلة" في gunicorn.

نعم ، تختلف مهلة العامل عن مهلة الطلب في حالة عدم التزامن. ولكن الطلبات التي تعمل لفترة طويلة دون أي استدعاءات للوظائف حيث يمكن أن يحدث "تبديل السياق" غير المتزامن (مثل "مأخذ التوصيل - القراءة / الكتابة") هي أسباب انقضاء مهلات العامل. وإلى جانب ذلك ، يمكن أن يكون هناك مهلة عند بدء تشغيل العامل (حيث لا يوجد طلب على الإطلاق). ولكن في سجلات Gunicorn ، لا توجد طريقة للتمييز بين هاتين الحالتين المختلفتين ، فهناك رسالة واحدة فقط "WORKER TIMEOUT".

هل يجب أن نضيف إعداد مهلة الطلب؟ من شأن ذلك أن يسمح للتطبيقات ذات الشركات الناشئة الطويلة بالتغلب على مهلة العامل.

لا أعتقد ذلك ، بسبب
1) قياس وقت تشغيل الطلب صعب ، لا يمكننا استخدام فرق التوقيت عند التسول وفي نهاية الطلب.
2) كما أعلم ، فإن التقاط مهلات "وحدات التنفيذ" (مقدار الكود الذي يتم تشغيله بين تبديل السياق) غير ممكن في gevent.

أي اقتراح بعد ذلك؟

إذا كانت هذه المشكلة بسبب المهلات المشروعة فقط ومن المحتمل أن تكون متتالية
المهلات بسبب تحميل الخادم الذي لم يكن موجودًا في أول تشغيل ، هل هناك
أي شيء تفعله هنا؟ أم أن هذه القضية قابلة للإغلاق ويتم التعامل معها بشكل أفضل
من الناحية التشغيلية على مستوى مختلف من البنية التحتية؟
في 30 تموز (يوليو) 2014 الساعة 1:14 ظهرًا ، كتب "Mkrtich" [email protected] :

لا أعتقد ذلك ، بسبب
1) قياس وقت تشغيل الطلب صعب ، لا يمكننا استخدام فرق التوقيت في
التسول وفي نهاية الطلب.
2) كما أعرف ، اصطياد مهلات "وحدات التنفيذ" (مقدار الكود
الذي يتم تشغيله بين تبديل السياق) غير ممكن في gevent.

-
قم بالرد على هذا البريد الإلكتروني مباشرة أو قم بعرضه على GitHub
https://github.com/benoitc/gunicorn/issues/588#issuecomment -50673040.

الاقتراح هو أن يكون لديك معلمتان للمهلة وسجلين مختلفين.
1) الأول هو معلمة المهلة الحالية التي ستعمل فقط أثناء معالجة الطلب.
2) الثانية ستكون مهلة بدء تشغيل العامل.

كما نرى هذه المشكلة

انتهى بنا المطاف بالتبديل إلى uWSGI من أجل Heroku وحققنا نجاحًا أفضل ... لم يكن إصلاحًا لـ Gunicorn ، كما أدرك ، لكنني اعتقدت أن الاقتراح قد يكون مفيدًا لشخص يرى هذه المشكلة على خادم الإنتاج الخاص به ويحتاج إلى حل عاجلاً وليس آجلاً .

nebstrebor حسنًا ، هل جربت الاقتراح لتقليل المهلة؟

CrazyPython تم إغلاق التذكرة. هل يمكنك فتح تذكرة جديدة تصف المشكلة التي تواجهها وكيف يمكننا إعادة إنتاجها؟ من المؤكد أنه سيساعد في معرفة ما إذا كانت هي نفس المشكلة ، شيء آخر وشريكه :)

نعم ، لم تحدث فرقًا ، كما هو مذكور أعلاه. كانت المشكلة متقطعة
بما يكفي (لم يكن بمقدورنا التكاثر أبدًا) وكارثية بما يكفي لدرجة أننا اضطررنا إلى ذلك
قم بهذه الخطوة (مر أكثر من عام). على الرغم من أنني أحب Gunicorn حقًا ،
ونستخدمه خارج Heroku بدون مشكلة.

بن روبرتس
CTO ومؤسس مشارك
Nutrislice، Inc.
[email protected]
خلية - 801-735-7845

في الثلاثاء 30 حزيران (يونيو) 2015 الساعة 8:08 صباحًا ، بينوا تشيسنو إخطارات @github.com
كتب:

nebstrebor https://github.com/nebstrebor جيد هل جربت
اقتراح لخفض المهلة؟

CrazyPython https://github.com/CrazyPython تم إغلاق التذكرة.
هل يمكنك فتح تذكرة جديدة تصف المشكلة التي تواجهها وكيف يمكننا ذلك
استنساخه؟ سيكون من المفيد بالتأكيد معرفة ما إذا كانت المشكلة نفسها ،
شيء آخر وشركاه :)

-
قم بالرد على هذا البريد الإلكتروني مباشرة أو قم بعرضه على GitHub
https://github.com/benoitc/gunicorn/issues/588#issuecomment -117199606.

أعتقد أننا نشهد هذه المشكلة أيضًا. تم تعليق كلا العاملين (- العمال 2) في بعض الطلبات طويلة المدى ، وتعرضوا للقتل في النهاية (- مهلة 20) ، ونرى على الفور اثنين من H13s ، ثم نبدأ في إعادة تشغيل H12s & WORKER TIMEOUT. واستمر هذا على مدار الدقائق العشر التالية ، ولم ينجح العمال أبدًا في معالجة أي طلب قبل انتهاء المهلة وإعادة تشغيلهم. لذلك ، أعدنا تشغيل dyno ، وهذا أصلحها.

أحد الأشياء المثيرة للاهتمام التي لاحظتها أنني لم أر أي شخص آخر يلاحظ - لقد رأينا H13s (الاتصال مغلق بدون استجابة) في بداية المشكلة ، ثم عندما أصدرنا أخيرًا SIGTERM ، رأينا فيضانًا من H13s - 48 على وجه الدقة ، وهو نفس عدد المهل الزمنية للعمال التي رأيناها (باستثناء الأولين اللذين رأينا H13 فوريًا لهما). لست متأكدًا تمامًا مما يعنيه ذلك ، لكن يبدو أنه مريب ....

ما هو H13s أو H12s؟ هل هذا شيء من heroku؟ كيف يتم إعطاء المنفذ الذي سيتم ربط البونكورن به؟ أظن أن وكيل heroku لا يكتشف أن المقبس مغلق.

أيضا أي عامل تستخدمه؟

نعم ، إنها رموز خطأ Heroku:
H12 - مهلة الطلب - عادةً 30 ثانية (https://devcenter.heroku.com/articles/error-codes#h12-request-timeout)
H13 - الاتصال مغلق بدون استجابة - (https://devcenter.heroku.com/articles/error-codes#h13-connection-closed-without-response)

تحرير: لقد لاحظت للتو أن gunicorn سيستخدم PORT إذا كان موجودًا كمتغير بيئة ، فهذه هي الطريقة التي يتم بها تكوين المنفذ.

نحن نستخدم عمال متزامنين.

ونسيت أيضًا أن أذكر أننا نجري gunicorn 19.3.0

إغلاق الإصدار نظرًا لعدم حدوث أي نشاط هناك منذ فترة طويلة. ربما يكون الحصول على مهلة متأخرة مفيدًا للتطبيقات التي تبدأ منذ فترة طويلة ولكن يجب القيام بذلك في بطاقة أخرى إذا لزم الأمر.

مرحبًا ، أواجه أيضًا نفس المشكلة مع gunicorn uvicorn على heroku باستخدام procfile المسؤول الجديد:

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

يقودني هذا إلى هذا السجل بمجرد تمهيد النظام:

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
هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات