Gunicorn: Sofortige Worker-Timeouts nach Anfragen mit langer Ausführungszeit

Erstellt am 8. Aug. 2013  ·  45Kommentare  ·  Quelle: benoitc/gunicorn

Wir haben ein sehr seltsames Problem mit Zeitüberschreitungen bei Anfragen erlebt, bei denen Gunicorn vor unserer Django-Anwendung auf Heroku ausgeführt wurde.

Im Wesentlichen tritt das Problem auf, wenn eine sehr lange laufende Anforderung an die Anwendung gestellt wird, die dazu führt, dass sie nach 30 Sekunden durch das Anforderungstimeout auf

[CRITICAL] WORKER TIMEOUT (pid:15)

Dies führt dazu, dass sofort eine Internal Server Error-Seite an den Client zurückgegeben wird. Dieses Verhalten ist nicht konsistent - manchmal wird die nächste Anfrage erfolgreich sein, manchmal nicht. Mein Verdacht ist, dass der Fehler auftritt, wenn die Anfrage von demselben Gunicorn-Mitarbeiter bearbeitet wird, der die lang andauernde Anfrage bearbeitet hat.

Wir betreiben Gunicorn direkt von Django wie folgt:

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

Andere relevante Konfigurationsparameter wie worker_connections und max_requests werden auf ihre Standardwerte gesetzt. Wir haben jedoch mit der Änderung dieser Einstellungen sowie der Anzahl der Arbeiter experimentiert, aber das oben beschriebene Problem tritt in allen von uns versuchten Fällen auf. Unsere aktuelle Gunicorn-Version ist 0.14.6 und wurde nach dem Upgrade auf 17.5 zurückgesetzt, falls dies die Ursache des Problems war. Leider tritt bei beiden Versionen das gleiche Verhalten auf.

Wir haben große Schwierigkeiten, die Ursache dieses Problems zu verstehen. Aus der oben verlinkten Heroku-Dokumentation:

Während der Router eine Antwort an den Client zurückgesendet hat, weiß Ihre Anwendung nicht, dass die von ihr verarbeitete Anfrage ein Timeout erreicht hat, und Ihre Anwendung wird die Anfrage weiter bearbeiten.

Ich gehe davon aus, dass dies bedeutet, dass ein Gunicorn-Mitarbeiter die Anfrage trotz der Tatsache, dass die ursprüngliche lang andauernde Anfrage aus Sicht des Clients abgelaufen ist, immer noch bearbeitet. Was mich verblüfft, ist, wie dies dazu führen würde, dass eine neue, nachfolgende Anfrage sofort ein Worker-Timeout auslöst, da die Worker gevent und damit asynchrone Threads verwenden, um Anfragen zu bearbeiten. Ich hätte gedacht, dass die erste, lang andauernde Anfrage wäre

  1. nicht blockierend, da mehrere Worker-Gevent-Threads vorhanden sind, und
  2. von Gunicorn getötet, bevor nachfolgende Anfragen auftreten, da das Standard-Request-Timeout für Gunicorn 30 Sekunden beträgt - identisch mit Herokus eigenem Request-Timeout.

Es ist erwähnenswert, dass die lang andauernden Anfragen eine Verbindung zu unserer PostgreSQL-Datenbank herstellen und mehrere komplexe Abfragen ausführen. Die Abstürze scheinen nur aufzutreten, nachdem die lang andauernde Verbindung dank Heroku während der Verbindung mit der DB ausgefallen ist. Wir haben dies auf unserem Testserver getestet, indem wir zwei separate Ansichten erstellt haben, von denen eine lange Abfragen gegen die Datenbank ausführt, bis ein Heroku-Timeout erreicht ist, und die andere einfach über die 30-Sekunden-Marke wartet, um das Heroku-Timeout zu erzeugen. Die erste Ansicht konnte bei der nächsten Anfrage zu Zeitüberschreitungen für Gunicorn-Worker führen, während die Ansicht "schlafen" dies nicht war.

Es wäre fantastisch, wenn jemand Einblicke in das zugrunde liegende Verhalten hat, das dieses Problem verursacht - alle zusätzlichen Informationen, die ich zur Diagnose des Problems bereitstellen kann, lassen Sie es mich bitte wissen. Ich hoffe, dass dies der richtige Weg ist, um mit einem solchen Problem umzugehen, und dass es noch nie zuvor angesprochen/angegangen wurde.

( FeaturWorker - Bugs -

Alle 45 Kommentare

@Jwpe Ausgezeichneter Fehlerbericht.

Das erste, was ich prüfen würde, ist, wenn Sie einen grün markierten PostgreSQL-Treiber verwenden. Früher gab es eine bestimmte Version, die Sie mit einem Affen-Patch verwenden mussten, damit dies richtig funktioniert. Ich kenne den aktuellen Stand der Dinge jetzt nicht. Aber das Timeout, das Sie eingefügt haben, ist ein Worker-Timeout und in einem der asynchronen Worker läuft das im Grunde auf "ein Greenlet hat sich seit über $timeout Sekunden nicht ergeben". Da Sie lang laufende PostgreSQL-Anforderungen beschreiben, würde ich dies zuerst untersuchen.

@davisp Danke für die schnelle Antwort dazu!

Ihrem Hinweis folgend, habe ich mir den psycopg2-Adapter angesehen - den wir verwenden, um unsere Django-App mit Postgres zu verbinden - und diesen Abschnitt der Dokumentation entdeckt, in dem es heißt:

Warnung: Psycopg-Verbindungen sind nicht sicher für grüne Threads und können nicht gleichzeitig von verschiedenen grünen Threads verwendet werden. Der Versuch, mehr als einen Befehl gleichzeitig mit einem Cursor pro Thread auszuführen, führt zu einem Fehler (oder zu einem Deadlock bei Versionen vor 2.4.2).
Daher wird Programmierern empfohlen, entweder die gemeinsame Nutzung von Verbindungen zwischen Coroutinen zu vermeiden oder eine bibliotheksfreundliche Sperre zu verwenden, um gemeinsam genutzte Verbindungen, z. B. für Pooling, zu synchronisieren.

Mit anderen Worten - psycopg2 mag keine grünen Fäden. Aufgrund des aufgetretenen Verhaltens würde ich vermuten, dass dies die Fehlerquelle ist. Der vorgeschlagene Weg, dieses Problem zu lösen, besteht laut den psycopg-Dokumenten darin, eine Bibliothek zu verwenden, die psycopg-Unterstützung für Coroutinen ermöglicht. Die empfohlene Bibliothek ist psycogreen .

Ich werde versuchen, das Problem auf unserem Testserver mit der psycogreen-Bibliothek nachzustellen und zu sehen, ob das Problem dadurch behoben wird. Hoffentlich kann ich relativ bald ein paar Ergebnisse vermelden.

@Jwpe Das sieht aus wie der Haken, an den ich mich erinnert habe.

@benoitc Vielleicht sollten wir das irgendwo in den Gunicorn-Dokumenten nennen? Ich bin mir jedoch nicht ganz sicher, wo der beste Ort wäre.

@davisp vielleicht in einem FAQ-Bereich?

hmppff vergessen, dass es bereits existierte (http://docs.gunicorn.org/en/latest/faq.html) Vielleicht könnten wir von dort einen Link zu einem Abschnitt zur Fehlerbehebung haben. Ich bin mir nicht sicher, aber wir könnten auch in einem solchen Abschnitt irgendwelche Informationen über virtualenv und andere Tricks verschieben.

Vielleicht eine Seite mit Vorbehalten oder "Hinweise zu grünen Fäden". Nicht super drückend.

Ich sah praktisch genau das gleiche Verhalten bei Heroku, das gunicorn mit gevent-Workern und einigen anderen ausführte, also wechselte ich zu synchronen Workern, wie in diesem Thread empfohlen, und sah im Grunde immer noch das gleiche ernsthafte Problem. Ich bekam einen H12 30 Sekunden Heroku Cutoff und wiederholte dann H12s und [CRITICAL] Worker Timeout Fehler, bis ich den gesamten Prüfstand zurücksetzte (manchmal eine Stunde oder mehr später oder bis die Max-Anforderungen erreicht wurden). Also habe ich das Gunicorn-Timeout auf 28 Sekunden angepasst, damit es eine Zeitüberschreitung hat, bevor Heroku es abschneidet. Das gleiche (oder sehr ähnliche) Problem tritt ein- oder zweimal am Tag auf und bleibt bestehen, bis der Master-Prozess neu gestartet wird, nur dieses Mal beginnt es mit einem H13 (Verbindung geschlossen), da Gunicorn ihn abschneidet. Zu diesen Zeiten gibt es keine nennenswerten Verkehrsspitzen.

Hier ist mein aktueller Profileintrag:

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

Detail der Veranstaltungsreihe:

Zuerst bekomme ich ein paar Anfragen, die wirklich lange zu dauern scheinen (5+ Sekunden), dann schlägt eine Anfrage mit einem H12-Timeout fehl (das Worker-Timeout unterbricht es) und ein paar weitere Anfragen werden beendet, aber mit außergewöhnlich langen Zeiten (20 Sekunden). Von da an ist es reine H11 30 Sekunden Heroku Cutoff's bis ich den Prüfstand neu starte.

Wir verwenden Gunicorn (v 18.0) als unseren Webserver (auf dem Python/Django läuft).

Wir betreiben newrelic, das die Ausfallzeiten und die wahnsinnig erhöhten Warteschlangenzeiten für Anfragen anzeigt, aber keinen anderen Einblick bietet. Es gab keine Durchsatzspitzen oder andere abnormale Bedingungen, die ich in NR sehen kann. Wir verwenden Papertrail für die Protokollbearbeitung und den Versand von Fehler-E-Mails.

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
Und diese "Todesspirale" von H12-Timeouts und [CRITICAL] WORKER TIMEOUT's geht so lange weiter, bis der Master-Prozess neu gestartet wird.

Habt ihr eine Idee ob das das gleiche Problem ist oder ein anderes? Irgendwelche Vorschläge zur Behebung? Ich würde denken, dass, da Gunicorn die Arbeitsprozesse nach einer Zeitüberschreitung abtötet und sie neu startet, sie in der Lage sind, die Dinge normal zu verarbeiten, aber es scheint, als würden Anfragen danach nicht einmal mehr bei ihnen eingehen. Vielleicht ist es ein Heroku-Problem.

:+1: Auch dieses Problem sehen.

Ich sehe dieses Problem auch bei Heroku

@sprynmr @richardkeen kannst du teilen, wie du gunicorn startest und jedes Protokoll, das du kannst? Es würde sehr helfen, das Problem zu beheben.

@nebstrebor was ist, wenn Sie die Anzahl der Anfragen nicht begrenzen?

Wir haben es so gestartet:
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

Selbst mit DEBUG auf Log-Ebene haben wir nicht viele Logs über das, was passierte, erhalten. Die Nichtverwendung von gevent hat das Problem für uns

@sprynmr Was ist, wenn Sie die maximale Anzahl von Anfragen entfernen? Auch welche Version von gevent?

Wir waren auf 1.0rc2 . Unsicher über die maximale Anzahl von Anfragen. Ich möchte es jetzt nicht wirklich für unsere Produktionsumgebung wieder einschalten.

Beim Lesen der Heroku-Seite zum Anforderungs-Timeout schlagen sie vor, das Anwendungs-Timeout well under 30 seconds, such as 10 or 15 . Haben Sie den Vorschlag mit dem Timeout-Parameter in gunicorn ausprobiert?

Wie auch immer, das Problem, das bei gevent auftritt, liegt wahrscheinlich an der Art und Weise, wie die Verbindungen gehandhabt werden. Die aktuelle Version des Workers erzeugt ein Greenlet / akzeptierte Verbindungen ohne wirkliche Überwachung dieses Greenlets. Was wahrscheinlich passieren wird, ist, dass einer der akzeptierten Sockets lange wartet und keine anderen Ereignisse verarbeitet werden, wodurch der Gunicorn-Worker neu gestartet wird. Aber ich muss nachsehen..

Interessant. Nein, das haben wir nicht probiert.

:+1: Das sehe ich auch in meiner Bewerbung. @Jwpe / @sprynmr hast du jemals eine Lösung für dieses Problem gefunden? Es sieht so aus, als ob seit mehr als 2 Monaten keine Aktivität zu diesem Problem aufgetreten ist. Ich bin gespannt, ob Sie etwas gefunden haben, um das Problem zu beheben.

Vielen Dank!

@dencold hast du es versucht https://github.com/benoitc/gunicorn/issues/588#issuecomment -29267541

Ich habe kein Konto bei Heroku, bin mir also nicht sicher, was es tut. Hast du auch die gleichen Logs?

Hallo @benoitc , @Jwpe und @nebstrebor gemeldet haben. Ich ziehe gerne die relevanten Teile heraus und füge sie hier hinzu, wenn dies zur Eingrenzung des Problems beitragen würde, lass es mich einfach wissen.

Ich werde Ihren Rat aus Ihrem früheren Kommentar befolgen und das Gunicorn-Timeout so konfigurieren, dass es niedriger ist als das Heroku-Router-Timeout und sehen, ob das hilft. Danke für den Vorschlag.

Es wäre hilfreich, die tatsächliche Ursache dieses kaskadierenden Ausfalls herauszufinden. Es ist wirklich seltsam zu sehen, wie ein Worker ausfällt und dann der gesamte Gunicorn-Server vollständig nicht mehr reagiert. Lassen Sie mich wissen, wenn ich etwas tun kann, um die Diagnose zu erleichtern. Ich kann dieses Timeout lokal nicht reproduzieren. Es scheint nur auf der Heroku-Infrastruktur aufzutreten.

Sorry @dencold, ich habe nie eine Lösung gefunden. Scheint ein sehr tiefgründiger mysteriöser Fehler zu sein, und ich hatte keine Zeit, damit zu kämpfen. Bin gespannt, ob dir das Timeout-Bit hilft. Zurückmelden.

@dencold verwendest du auch new relic?

@benoitc yep, wir verwenden auch neues Relikt.

@dencold ebenfalls, wir haben dieses Problem nie erfolgreich gelöst. Wir hatten keine Zeit, um herauszufinden, was die Fehler verursachte, und mussten uns darauf konzentrieren, die Dauer der ursprünglichen Anfragen zu reduzieren. Die kritische Natur des Fehlers - da er benutzerseitig war - führte uns jedoch dazu, die WSGI-Server zu wechseln, um das Problem in der Zwischenzeit zu vermeiden. Daher haben wir keine weiteren Experimente durchgeführt, um das Problem weiter zu kategorisieren.

@Jwpe hast du zumindest die vorgeschlagene Lösung ausprobiert? Auch das Ergebnis ist seltsam und ich reproduziere das nie mit Gunicorn allein.

Ich hatte die Cutoff-Zeit auf 15 Sekunden gesenkt und sah das Problem immer noch

Am Sonntag, 26. Januar 2014, Benoit Chesneau [email protected]
schrieb:

@Jwpe https://github.com/Jwpe hast du zumindest das vorgeschlagene ausprobiert
Lösung? Auch das Ergebnis ist komisch und das reproduziere ich nie mit gunicorn
von selbst.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf Gi tHub anhttps://github.com/benoitc/gunicorn/issues/588#issuecomment -33316333
.

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

@Jwpe / @nebstrebor vielen Dank für Ihre Rückmeldung zu diesem Thema.

@benoitc wir haben die vorgeschlagene Timeout-Lösung in unserer heroku-Instanz implementiert. Ich werde das in den nächsten Tagen genau beobachten. Werde wieder posten, wenn nach dem neuen Timeout das gleiche Problem auftaucht.

Danke nochmal an alle für die Hilfe. Gut zu wissen, dass ich nicht der einzige mit diesem Problem bin. Hoffentlich können wir der Ursache auf den Grund gehen.

@benoitc wollte nur berichten, dass es ungefähr zwei Wochen mit dem niedrigeren Timeout her ist. Wir haben einige Worker-Timeouts gesehen, aber keine, die dazu führen, dass der gesamte Gunicorn-Prozess nicht mehr reagiert. Dies scheint das Problem zu lösen, aber ich bin mir immer noch nicht sicher, warum 30s-Timeouts den Kaskadierungsfehler überhaupt verursacht haben.

Wollte dich nur auf dem Laufenden halten. Danke nochmal für die ganze Hilfe hier!

Der gleiche [CRITICAL] WORKER TIMEOUT-Fehler beim Ausführen von Django mit gunicorn in einem Raspberry PI.

Keine Neuigkeiten.

Ich erhalte das gleiche [KRITISCHE] WORKER TIMEOUT.
Das Problem ist, dass das Gunicorn nach dem echten Timeout des Workers (lange Anfrage) den Worker tötet und versucht, einen neuen zu erzeugen, aber der neue Worker konnte nicht innerhalb des TIMEOUT-Limits starten und erreicht nicht die Stelle, an der er dem übergeordneten Prozess mitteilt, dass dies der Fall ist live, also tötet es das Gunicorn immer wieder :(. In unserem Fall bezog sich das Problem auf Gevent und Sentry(https://github.com/getsentry/raven-python/issues/305). Sentry hängt einfach beim Startup .
Übrigens: Es ist hilfreich, ein separates Timeout für die Startzeit des Workers und einige zusätzliche Protokolle innerhalb eines Workers zu haben, die nicht innerhalb einer "Timeout"-Zeit gestartet werden können.

Das Timeout ist kein Request-Timeout, außer auf dem Sync-Worker. Die anderen Arbeiter schlagen auch bei langen Anfragen immer noch Herzschlag für den Schiedsrichter. Die Timeout-Zeit ist in diesem Fall die Start-Timeout-Zeit.

In gunicorn gibt es gewissermaßen kein "Request-Timeout".

Ja, das Worker-Timeout unterscheidet sich vom Request-Timeout in async. Aber lange laufende Anforderungen ohne Funktionsaufrufe, bei denen asynchrone "Kontextwechsel" auftreten können (wie "Socket - Lesen/Schreiben") sind die Ursachen für Worker-Timeouts. Außerdem kann es beim Start des Workers zu einer Zeitüberschreitung kommen (wo es überhaupt keine Anfrage gibt). Aber in den Gunicorn-Protokollen gibt es keine Möglichkeit, diese 2 verschiedenen Fälle zu unterscheiden, es gibt nur eine Meldung "WORKER TIMEOUT".

Sollen wir eine Einstellung für das Zeitlimit für Anfragen hinzufügen? Dadurch würden Apps mit langen Startzeiten das Worker-Timeout verkürzen.

Glaube nicht, wegen
1) Die Laufzeit der Anfrage zu messen ist schwierig, wir können die Zeitdifferenz am Anfang und am Ende der Anfrage nicht verwenden.
2) Wie ich weiß, ist das Abfangen von Timeouts von "Ausführungseinheiten" (die Menge an Code, die zwischen Kontextwechseln ausgeführt wird) in gevent nicht möglich.

Irgendein Vorschlag dann?

Wenn dieses Problem nur auf legitime Zeitüberschreitungen und potenzielle Kaskadierungen zurückzuführen ist
Timeouts aufgrund von Serverlast, die beim ersten Durchlauf nicht vorhanden sind, gibt es?
hier irgendwas zu tun? Oder ist dieses Thema schließbar und wird besser gehandhabt
operativ auf einer anderen Infrastrukturebene?
Am 30. Juli 2014 um 13:14 schrieb "Mkrtich" [email protected] :

Glaube nicht, wegen
1) Das Messen der Anforderungslaufzeit ist schwierig, wir können den Zeitunterschied nicht verwenden
betteln und am Ende der Bitte.
2) Wie ich weiß, werden Timeouts von "Ausführungseinheiten" (die Menge an Code)
das läuft zwischen Kontextwechsel) ist in gevent nicht möglich.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/benoitc/gunicorn/issues/588#issuecomment -50673040.

Es wird empfohlen, 2 Zeitüberschreitungsparameter und 2 verschiedene Protokolle zu verwenden.
1) Einer ist der aktuelle Timeout-Parameter, der nur während der Anfragebearbeitung funktioniert.
2) Das zweite ist die Zeitüberschreitung beim Worker-Start.

Sehe auch dieses Problem

Am Ende wechselten wir für Heroku zu uWSGI und hatten besseren Erfolg ... keine Lösung für Gunicorn, ist mir klar, aber ich dachte, der Vorschlag könnte für jemanden hilfreich sein, der dieses Problem auf seinem Produktionsserver sieht und früher als später eine Lösung benötigt .

@nebstrebor gut, hast du den Vorschlag ausprobiert, das Timeout zu

@CrazyPython das Ticket wurde geschlossen. Können Sie ein neues Ticket eröffnen und beschreiben, welches Problem Sie haben und wie wir es reproduzieren können? Es würde auf jeden Fall helfen herauszufinden, ob es das gleiche Problem ist, etwas anderes und Co :)

Ja, es hat, wie oben erwähnt, keinen Unterschied gemacht. Das Problem war sporadisch
genug (konnte sich nie reproduzieren) und katastrophal genug, dass wir es mussten
Machen Sie diesen Schritt (es ist mehr als ein Jahr her). Ich mag Gunicorn aber sehr,
und wir verwenden es ohne Probleme außerhalb von Heroku.

Ben Roberts
CTO & Mitgründer
Nutrislice, Inc.
[email protected]
Zelle - 801-735-7845

Am Dienstag, 30. Juni 2015 um 08:08, Benoit Chesneau [email protected]
schrieb:

@nebstrebor https://github.com/nebstrebor gut hast du das probiert
Vorschlag, das Timeout zu verkürzen?

@CrazyPython https://github.com/CrazyPython das Ticket wurde geschlossen.
Können Sie ein neues Ticket eröffnen, beschreiben Sie Ihr Problem und wie wir das können?
reproduzieren? Es wäre definitiv hilfreich herauszufinden, ob es sich um das gleiche Problem handelt,
noch was und co :)


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/benoitc/gunicorn/issues/588#issuecomment -117199606.

Ich denke, wir sehen dieses Problem auch. Beide Arbeiter (--worker 2) wurden bei einigen lang andauernden Anfragen aufgehängt, wurden schließlich getötet (--timeout 20), und wir sehen sofort zwei H13s, und dann fangen wir an, H12s zu bekommen & WORKER TIMEOUT startet neu. In den nächsten 10 Minuten ging dies so weiter, dass die Worker eine Anfrage nie erfolgreich verarbeiteten, bevor sie das Timeout erreichten und neu gestartet wurden. Also haben wir den Prüfstand neu gestartet und das hat es behoben.

Eine interessante Sache, die mir aufgefallen ist, dass ich keinen anderen Hinweis gesehen habe - wir sehen zu Beginn der Ausgabe zwei H13 (Verbindung geschlossen ohne Antwort), und dann, als wir endlich den SIGTERM herausgegeben haben, sahen wir eine Flut von H13 - 48 um genau zu sein, das ist die gleiche Anzahl von WORKER TIMEOUTs, die wir gesehen haben (mit Ausnahme der ersten beiden, für die wir sofort H13 gesehen haben). Ich bin mir nicht ganz sicher, was das bedeutet, aber es scheint verdächtig zu sein....

Was ist H13s oder H12s? Ist das etwas von Heroku? Wie wird der Port angegeben, an dem Gunicorn gebunden wird? Ich vermute, dass der Heroku-Proxy nicht erkennt, dass der Socket geschlossen ist.

Und welchen Worker verwendest du?

Ja, das sind Heroku-Fehlercodes:
H12 - Request Timeout - normalerweise 30s (https://devcenter.heroku.com/articles/error-codes#h12-request-timeout)
H13 - Verbindung ohne Antwort geschlossen - (https://devcenter.heroku.com/articles/error-codes#h13-connection-closed-ohne-antwort)

Bearbeiten: Mir ist gerade aufgefallen, dass gunicorn PORT verwendet, wenn es als Umgebungsvariable existiert, also ist der Port so konfiguriert.

Wir verwenden synchrone Worker.

Und ich habe auch vergessen zu erwähnen, dass wir gunicorn 19.3.0 ausführen

Schließung der Ausgabe, da dort seit langer Zeit keine Aktivität mehr stattgefunden hat. Vielleicht wäre ein verzögertes Timeout für lange Startanwendungen gut, aber das sollte bei Bedarf in einem anderen Ticket erfolgen.

Hey, ich habe auch das gleiche Problem mit Gunicorn Uvicorn auf Heroku mit dem New-Relic-Admin-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

Dies führt mich zu diesem Protokoll, sobald das System gebootet wird:

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
War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

benoitc picture benoitc  ·  4Kommentare

twosigmajab picture twosigmajab  ·  4Kommentare

leonardbinet picture leonardbinet  ·  4Kommentare

zenglingyu picture zenglingyu  ·  4Kommentare

thomasjungblut picture thomasjungblut  ·  3Kommentare