Zeitüberschreitungsfehler des Gunicorn-Arbeiters


182

Ich habe Gunicorn mit 3 Arbeitern, 30 Arbeiterverbindungen und Eventlet-Arbeiterklasse eingerichtet. Es ist hinter Nginx eingerichtet. Nach jeweils wenigen Anfragen sehe ich dies in den Protokollen.

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

Warum passiert dies? Wie kann ich herausfinden, was falsch läuft?

Vielen Dank


2
Sie konnten das Problem lösen? Bitte teilen Sie Ihre Gedanken mit, da ich auch dabei geblieben bin. Gunicorn==19.3.1undgevent==1.0.1
Black_Rider

2
Habe die Lösung dafür gefunden. Das Timeout wurde auf einen sehr großen Wert erhöht und dann konnte ich die Stapelverfolgung sehen
Black_Rider

Antworten:


153

Wir hatten das gleiche Problem mit Django + Nginx + Gunicorn. Aus der Gunicorn-Dokumentation haben wir das Graceful-Timeout konfiguriert, das fast keinen Unterschied machte.

Nach einigen Tests haben wir die Lösung gefunden. Der zu konfigurierende Parameter lautet: Zeitüberschreitung (und keine ordnungsgemäße Zeitüberschreitung). Es funktioniert wie eine Uhr.

Dann mach's:

1) Öffnen Sie die Gunicorn-Konfigurationsdatei

2) Stellen Sie den TIMEOUT auf das ein, was Sie brauchen - der Wert ist in Sekunden angegeben

NUM_WORKERS=3
TIMEOUT=120

exec gunicorn ${DJANGO_WSGI_MODULE}:application \
--name $NAME \
--workers $NUM_WORKERS \
--timeout $TIMEOUT \
--log-level=debug \
--bind=127.0.0.1:9000 \
--pid=$PIDFILE

9
Danke das ist die richtige Antwort. Und dann, um Ressourcen mit vielen gleichzeitigen Verbindungen zu sparen: pip install geventdann worker_class geventin Ihrer Konfigurationsdatei oder -k geventin der Befehlszeile.
little_birdie

2
Ich laufe mit Supervisor, also habe ich es zu conf.d / app.conf hinzugefügt :command=/opt/env_vars/run_with_env.sh /path/to/environment_variables /path/to/gunicorn --timeout 200 --workers 3 --bind unix:/path/to/socket server.wsgi:application
lukik

31

In der Google Cloud --timeout 90Fügen Sie einfach den Einstiegspunkt in hinzuapp.yaml

entrypoint: gunicorn -b :$PORT main:app --timeout 90

21

Führen Sie Gunicorn mit --log-level=DEBUG.

Es sollte Ihnen einen App-Stack-Trace geben.


41
In meinem Fall nicht.
Joe

16
es ist jetzt--log-level debug
psychok7

4
Ich würde gerne eine Spur bekommen, aber keiner von ihnen arbeitet hier mit Gunicorn 19.4.5. Debug-Inhalte werden angezeigt, daher wurde das Flag vermutlich erkannt, beim Timeout jedoch nicht die Stapelverfolgung.
Orzel


6

Sie müssen eine andere Worker-Typ-Klasse verwenden, eine asynchrone wie gevent oder tornado. Weitere Erläuterungen finden Sie hier: Erste Erläuterung:

Möglicherweise möchten Sie auch Eventlet oder Gevent installieren, wenn Sie erwarten, dass Ihr Anwendungscode während der Anforderungsverarbeitung für längere Zeit pausieren muss

Das Zweite :

Die Standard-Synchronarbeiter gehen davon aus, dass Ihre Anwendung in Bezug auf CPU- und Netzwerkbandbreite ressourcengebunden ist. Im Allgemeinen bedeutet dies, dass Ihre Anwendung nichts tun sollte, was eine undefinierte Zeit in Anspruch nimmt. Beispielsweise erfüllt eine Anfrage an das Internet diese Kriterien. Irgendwann fällt das externe Netzwerk so aus, dass sich Clients auf Ihren Servern stapeln.


Wie würde ich eigentlich von einer so anderen Arbeiterklasse Gebrauch machen?
Frederick Nord

6

Ich hatte ein sehr ähnliches Problem. Ich habe auch versucht, mit "runserver" zu prüfen, ob ich etwas anderes als eine Nachricht finden konnte Killed

Also dachte ich, es könnte ein Ressourcenproblem sein, und ich gab der Instanz mehr RAM, und es funktionierte.


1
Ich sah dieses Problem sogar mit gevent und das Timeout richtig eingestellt, nicht
genügend

6

WORKER TIMEOUTbedeutet, dass Ihre Anwendung nicht innerhalb eines festgelegten Zeitraums auf die Anfrage antworten kann. Sie können dies mit Gunicorn Timeout-Einstellungen einstellen . Einige Anwendungen benötigen mehr Zeit für die Antwort als andere.

Eine andere Sache, die dies beeinflussen kann, ist die Auswahl des Arbeitertyps

Die Standard-Synchronarbeiter gehen davon aus, dass Ihre Anwendung in Bezug auf CPU- und Netzwerkbandbreite ressourcengebunden ist. Im Allgemeinen bedeutet dies, dass Ihre Anwendung nichts tun sollte, was eine undefinierte Zeit in Anspruch nimmt. Ein Beispiel für etwas, das eine unbestimmte Zeit in Anspruch nimmt, ist eine Anfrage an das Internet. Irgendwann fällt das externe Netzwerk so aus, dass sich Clients auf Ihren Servern stapeln. In diesem Sinne profitiert jede Webanwendung, die ausgehende Anforderungen an APIs stellt, von einem asynchronen Worker.

Als ich das gleiche Problem wie Sie hatte (ich habe versucht, meine Anwendung mit Docker Swarm bereitzustellen), habe ich versucht, das Zeitlimit zu erhöhen und einen anderen Typ von Worker-Klasse zu verwenden. Aber alles ist gescheitert.

Und dann wurde mir plötzlich klar, dass ich meine Ressourcen für den Dienst in meiner Erstellungsdatei zu niedrig begrenzte . Dies ist die Sache, die die Anwendung in meinem Fall verlangsamt hat

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

Ich empfehle Ihnen daher, zunächst zu überprüfen, was Ihre Bewerbung verlangsamt


4

Dauert dieser Endpunkt zu lange?

Möglicherweise verwenden Sie eine Flasche ohne assynchrone Unterstützung, sodass jede Anforderung den Anruf blockiert. Fügen Sie den geventWorker hinzu, um asynchrone Unterstützung zu erstellen, ohne dies zu erschweren .

Mit gevent erzeugt ein neuer Anruf einen neuen Thread und Ihre App kann weitere Anfragen empfangen

pip install gevent
gunicon .... --worker-class gevent

1
einfache Optimierung .. rettete meinen Tag!
penduDev

2

Ich habe das gleiche Problem in Docker.

In Docker halte ich geschultes LightGBMModell + Flaskbediene Anfragen. Als HTTP-Server habe ich verwendet gunicorn 19.9.0. Wenn ich meinen Code lokal auf meinem Mac-Laptop ausführte, funktionierte alles einwandfrei, aber als ich die App in Docker ausführte, froren meine POST-JSON-Anforderungen einige Zeit ein, und der gunicornWorker war mit [CRITICAL] WORKER TIMEOUTAusnahme fehlgeschlagen .

Ich habe unzählige verschiedene Ansätze ausprobiert, aber der einzige, der mein Problem gelöst hat, war das Hinzufügen worker_class=gthread.

Hier ist meine komplette Konfiguration:

import multiprocessing

workers = multiprocessing.cpu_count() * 2 + 1
accesslog = "-" # STDOUT
access_log_format = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(q)s" "%(D)s"'
bind = "0.0.0.0:5000"
keepalive = 120
timeout = 120
worker_class = "gthread"
threads = 3

Einige Ihrer anderen Antworten wurden ebenfalls positiv bewertet, nur diese ist nicht genug: P
Achala Dissanayake


1

Timeout ist ein Schlüsselparameter für dieses Problem.

es passt jedoch nicht zu mir.

Ich fand, dass es keinen Gunicorn Timeout-Fehler gibt, wenn ich Arbeiter = 1 setze.

Wenn ich meinen Code durchschaue , habe ich eine Socket-Verbindung (socket.send & socket.recv) in Server Init gefunden.

socket.recv blockiert meinen Code und deshalb tritt immer eine Zeitüberschreitung auf, wenn Arbeiter> 1 sind

Ich hoffe, den Leuten, die ein Problem mit mir haben, einige Ideen zu geben


1

Das hat bei mir funktioniert:

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

Wenn Sie eventlethinzugefügt haben:

--worker-class=eventlet

Wenn Sie geventhinzugefügt haben:

--worker-class=gevent

0

Für mich bestand die Lösung darin --timeout 90, meinen Einstiegspunkt zu erweitern, aber es funktionierte nicht, da ich ZWEI Einstiegspunkte definiert hatte, einen in app.yaml und einen in meiner Docker-Datei. Ich habe den nicht verwendeten Einstiegspunkt gelöscht und --timeout 90den anderen hinzugefügt .

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.