Errore di timeout del lavoratore Gunicorn


182

Ho installato Gunicorn con 3 lavoratori e 30 connessioni di lavoro e utilizzando la classe di lavoro dell'evento. È installato dietro Nginx. Dopo ogni poche richieste, lo vedo nei registri.

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

Perché sta succedendo? Come posso capire cosa non va?

Grazie


2
Sei stato in grado di risolvere il problema? Per favore, condividi i tuoi pensieri mentre anche io mi sono bloccato. Gunicorn==19.3.1egevent==1.0.1
Black_Rider

2
Ho trovato la soluzione per questo. Aumentato il timeout a un valore molto grande e quindi sono stato in grado di vedere la traccia dello stack
Black_Rider

Risposte:


156

Abbiamo avuto lo stesso problema con Django + nginx + gunicorn. Dalla documentazione di Gunicorn abbiamo configurato il grazioso timeout che non ha fatto quasi alcuna differenza.

Dopo alcuni test, abbiamo trovato la soluzione, il parametro da configurare è: timeout (e non timeout grazioso). Funziona come un orologio ..

Quindi, fai:

1) apri il file di configurazione di gunicorn

2) imposta il TIMEOUT su tutto ciò di cui hai bisogno: il valore è in secondi

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
Grazie questa è la risposta giusta. E poi, al fine di risparmiare risorse con molte connessioni simultanee:, pip install geventquindi worker_class geventnel tuo file di configurazione o -k geventsulla riga di comando.
little_birdie,

2
Sono in esecuzione con il supervisore, quindi l'ho aggiunto a conf.d / app.conf :command=/opt/env_vars/run_with_env.sh /path/to/environment_variables /path/to/gunicorn --timeout 200 --workers 3 --bind unix:/path/to/socket server.wsgi:application
lukik il

31

Su Google Cloud Basta aggiungere --timeout 90al punto di accesso inapp.yaml

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

21

Corri Gunicorn con --log-level=DEBUG.

Dovrebbe darti una traccia dello stack dell'app.


41
Non nel mio caso.
Joe,

16
è ora--log-level debug
psychok7

4
Mi piacerebbe avere uno stracktrace, ma nessuno di loro lavora qui, usando Gunicorn 19.4.5. Viene visualizzato materiale di debug, quindi immagino che la bandiera sia stata riconosciuta, ma non stacktrace al timeout.
Orzel,


6

È necessario utilizzare un altro tipo di classe lavoratore asincrono come gevent o tornado, vedere questo per ulteriori spiegazioni: Prima spiegazione:

È inoltre possibile installare Eventlet o Gevent se si prevede che il codice dell'applicazione potrebbe dover essere messo in pausa per lunghi periodi di tempo durante l'elaborazione della richiesta

Il secondo :

I lavoratori sincroni predefiniti presumono che l'applicazione sia legata alle risorse in termini di larghezza di banda della CPU e della rete. In genere questo significa che l'applicazione non dovrebbe fare nulla che richieda una quantità indefinita di tempo. Ad esempio, una richiesta a Internet soddisfa questi criteri. Ad un certo punto la rete esterna si guasterà in modo tale che i client si accumuleranno sui tuoi server.


Come potrei effettivamente utilizzare una classe lavoratrice così diversa?
Federico Nord,

6

Ho avuto un problema molto simile, ho anche provato a utilizzare "RunServer" per vedere se riuscivo a trovare qualcosa, ma tutto quello che avevo era un messaggio Killed

Quindi ho pensato che potesse essere un problema di risorse e sono andato avanti per dare più RAM all'istanza, e ha funzionato.


1
Stavo vedendo questo problema anche con gevent e il timeout impostato correttamente, memoria
insufficiente

6

WORKER TIMEOUTsignifica che l'applicazione non può rispondere alla richiesta in un periodo di tempo definito. Puoi impostarlo usando le impostazioni di timeout del gunicorno . Alcune applicazioni richiedono più tempo per la risposta di altre.

Un'altra cosa che può influire su questo è la scelta del tipo di lavoratore

I lavoratori sincroni predefiniti presumono che l'applicazione sia limitata in termini di risorse in termini di larghezza di banda della CPU e della rete. In genere questo significa che l'applicazione non dovrebbe fare nulla che richieda una quantità indefinita di tempo. Un esempio di qualcosa che richiede una quantità indefinita di tempo è una richiesta a Internet. Ad un certo punto la rete esterna si guasterà in modo tale che i client si accumuleranno sui tuoi server. Pertanto, in questo senso, qualsiasi applicazione Web che invia richieste in uscita alle API trarrà vantaggio da un lavoratore asincrono.

Quando ho avuto lo stesso problema del tuo (stavo provando a distribuire la mia applicazione usando Docker Swarm), ho provato ad aumentare il timeout e ad usare un altro tipo di classe operaia. Ma tutto fallì.

E poi improvvisamente mi sono reso conto che stavo limitando la mia risorsa troppo bassa per il servizio all'interno del mio file di composizione. Questa è la cosa che ha rallentato l'applicazione nel mio caso

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

Quindi ti consiglio di verificare quale cosa rallenta l'applicazione in primo luogo


4

Questo endpoint sta impiegando troppo tempo?

Forse stai usando il pallone senza supporto assincrono, quindi ogni richiesta bloccherà la chiamata. Per creare un supporto asincrono senza rendere difficile, aggiungere il geventlavoratore.

Con gevent, una nuova chiamata genererà un nuovo thread e la tua app sarà in grado di ricevere più richieste

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

1
semplice modifica .. mi ha salvato la giornata!
penduDev

3

Ho lo stesso problema in Docker.

In Docker tengo addestrato LightGBMmodello + Flaskrichieste di servizio. Come server HTTP ho usato gunicorn 19.9.0. Quando eseguivo il mio codice localmente sul mio laptop Mac, tutto funzionava perfettamente, ma quando eseguivo l'app in Docker le mie richieste POST JSON si bloccavano da un po 'di tempo, quindi il gunicornlavoratore aveva fallito con l' [CRITICAL] WORKER TIMEOUTeccezione.

Ho provato tonnellate di approcci diversi, ma l'unico a risolvere il mio problema era l'aggiunta worker_class=gthread.

Ecco la mia configurazione completa:

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

ha votato alcune delle tue altre risposte, ma solo questa non è abbastanza: P
Achala Dissanayake,


1

il timeout è un parametro chiave per questo problema.

tuttavia non è adatto a me.

ho riscontrato che non è presente un errore di timeout di Gunicorn quando imposto lavoratori = 1.

quando guardo il mio codice, ho trovato alcuni socket connect (socket.send & socket.recv) nell'iniz server.

socket.recv bloccherà il mio codice ed è per questo che scade sempre quando i lavoratori> 1

spero di dare alcune idee alle persone che hanno qualche problema con me


1

Questo ha funzionato per me:

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

Se hai eventletaggiunto:

--worker-class=eventlet

Se hai geventaggiunto:

--worker-class=gevent

0

Per me, la soluzione era quella di aggiungere --timeout 90al mio punto di entrata, ma non funzionava perché avevo DUE punti di entrata definiti, uno in app.yaml e un altro nel mio Dockerfile. Ho eliminato il punto di accesso non utilizzato e aggiunto --timeout 90nell'altro.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.