Gunicorn: "Trabajador de arranque" se repite infinitamente a pesar de que no hay señales de salida

Creado en 11 dic. 2017  ·  65Comentarios  ·  Fuente: benoitc/gunicorn

Estoy intentando instalar Gunicorn en Docker. Funciona bien a nivel local y la imagen de producción es exactamente la misma que la imagen local, pero obtengo este comportamiento extraño en el motor de producción de Docker:

ml-server_1     | [2017-12-11 13:18:50 +0000] [1] [INFO] Starting gunicorn 19.7.1
ml-server_1     | [2017-12-11 13:18:50 +0000] [1] [DEBUG] Arbiter booted
ml-server_1     | [2017-12-11 13:18:50 +0000] [1] [INFO] Listening at: http://0.0.0.0:80 (1)
ml-server_1     | [2017-12-11 13:18:50 +0000] [1] [INFO] Using worker: sync
ml-server_1     | [2017-12-11 13:18:50 +0000] [8] [INFO] Booting worker with pid: 8
ml-server_1     | [2017-12-11 13:18:50 +0000] [1] [DEBUG] 1 workers
ml-server_1     | Using TensorFlow backend.
ml-server_1     | [2017-12-11 13:18:54 +0000] [11] [INFO] Booting worker with pid: 11
ml-server_1     | Using TensorFlow backend.
ml-server_1     | [2017-12-11 13:18:58 +0000] [14] [INFO] Booting worker with pid: 14
ml-server_1     | Using TensorFlow backend.
ml-server_1     | [2017-12-11 13:19:02 +0000] [17] [INFO] Booting worker with pid: 17
ml-server_1     | Using TensorFlow backend.

Parece que gunicorn está arrancando a los trabajadores cada 4-5 segundos, a pesar de que no hay mensajes de error aparentes o señales de salida. Este comportamiento continúa indefinidamente hasta que se termina.

¿Es posible que un trabajador pueda salir sin registrar nada en stderr / stdout, o que el árbitro genere trabajadores infinitamente?

Dado que son la misma imagen de la ventana acoplable, están ejecutando exactamente el mismo código, exactamente en la misma arquitectura, por lo que estoy realmente confundido sobre qué podría ser esto (¿error?). ¡Cualquier ayuda muy apreciada!

Improvement help wanted

Comentario más útil

Solo una actualización, el problema para mí era en realidad un error de memoria y se solucionó cuando se solucionó el problema de memoria.

Todos 65 comentarios

ssh -ing en el contenedor de Docker me llevó a encontrar este error:

Illegal instruction (core dumped)

¿Quizás Gunicorn debería sacar a la luz errores como este en lugar de tragarlos, o manejarlos de manera diferente? No estoy seguro, ¡solo pensé en plantear esto ya que podría ayudar a alguien más!

Gracias por informar del problema.

Si puede averiguar dónde sucede esto, sería muy útil.

Quizás podamos agregar el registro cuando los trabajadores salgan. Por lo general, el propio trabajador registra, pero si se mata de forma muy abrupta, no lo hará.

¡No hay problema!

Parece que hay un problema con Spacy que acabo de agregar a este hilo: https://github.com/explosion/spaCy/issues/1589

De todos modos, está causando un SIGILL como strace confirma:

--- SIGILL {si_signo=SIGILL, si_code=ILL_ILLOPN, si_addr=0x7ff48bbe6cea} ---
+++ killed by SIGILL (core dumped) +++
Illegal instruction (core dumped)

Supongo que sería bueno si gunicorn pudiera identificar esto y registrar un error en lugar de reiniciar el trabajador de manera fantasma, ¡pero sé muy poco sobre cómo funcionan los códigos de salida!

Algunos códigos de salida definitivamente tienen significados especiales y probablemente podríamos registrarlos.
http://tldp.org/LDP/abs/html/exitcodes.html

¡Suena bien! Además, si el código de salida no es un código de salida reservado (como en este caso), sería genial si pudiera registrarse (sin una explicación) para que sea evidente que el trabajador está terminando 🙂

Tengo un problema similar, gunicorn arranca un nuevo trabajador siempre que hago una solicitud http. No obtengo ninguna respuesta, solo reinicia el nuevo trabajador siempre. Registro de Strace de dos solicitudes http:

select(4, [3], [], [], {1, 0})          = 0 (Timeout)
fstat(6, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(7, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(9, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(8, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
select(4, [3], [], [], {1, 0})          = ? ERESTARTNOHAND (To be restarted if no handler)
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_KILLED, si_pid=510, si_uid=0, si_status=SIGSEGV, si_utime=160, si_stime=32} ---
getpid()                                = 495
rt_sigreturn({mask=[]})                 = -1 EINTR (Interrupted system call)
wait4(-1, [{WIFSIGNALED(s) && WTERMSIG(s) == SIGSEGV && WCOREDUMP(s)}], WNOHANG, NULL) = 510
lseek(8, 0, SEEK_CUR)                   = 0
close(8)                                = 0
wait4(-1, 0x7ffd455ad844, WNOHANG, NULL) = 0
write(4, ".", 1)                        = 1
select(4, [3], [], [], {0, 840340})     = 1 (in [3], left {0, 840338})
read(3, ".", 1)                         = 1
read(3, 0x7f2682025fa0, 1)              = -1 EAGAIN (Resource temporarily unavailable)
fstat(6, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(7, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(9, {st_mode=S_IFREG, st_size=0, ...}) = 0
umask(0)                                = 022
getpid()                                = 495
open("/tmp/wgunicorn-q4aa72u7", O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW|O_CLOEXEC, 0600) = 8
fcntl(8, F_SETFD, FD_CLOEXEC)           = 0
chown("/tmp/wgunicorn-q4aa72u7", 0, 0)  = 0
umask(022)                              = 0
unlink("/tmp/wgunicorn-q4aa72u7")       = 0
fstat(8, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
ioctl(8, TIOCGWINSZ, 0x7ffd455b8e50)    = -1 ENOTTY (Not a tty)
lseek(8, 0, SEEK_CUR)                   = 0
lseek(8, 0, SEEK_CUR)                   = 0
rt_sigprocmask(SIG_BLOCK, ~[], [], 8)   = 0
fork()                                  = 558
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
select(0, NULL, NULL, NULL, {0, 37381}[2017-12-28 17:50:23 +0000] [558] [INFO] Booting worker with pid: 558
) = 0 (Timeout)
select(4, [3], [], [], {1, 0}loading test-eu-ovh settings
)          = 0 (Timeout)
fstat(6, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(7, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(9, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(8, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
select(4, [3], [], [], {1, 0}
)          = 0 (Timeout)
fstat(6, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(7, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(9, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(8, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
select(4, [3], [], [], {1, 0})          = 0 (Timeout)
fstat(6, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(7, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(9, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(8, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
select(4, [3], [], [], {1, 0})          = 0 (Timeout)
fstat(6, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(7, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(9, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(8, {st_mode=S_IFREG, st_size=0, ...}) = 0
select(4, [3], [], [], {1, 0})          = 0 (Timeout)
fstat(6, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(7, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(9, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(8, {st_mode=S_IFREG, st_size=0, ...}) = 0
select(4, [3], [], [], {1, 0})          = 0 (Timeout)
fstat(6, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(7, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(9, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(8, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
select(4, [3], [], [], {1, 0})          = 0 (Timeout)
fstat(6, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(7, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(9, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(8, {st_mode=S_IFREG, st_size=0, ...}) = 0
select(4, [3], [], [], {1, 0})          = ? ERESTARTNOHAND (To be restarted if no handler)
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_KILLED, si_pid=499, si_uid=0, si_status=SIGSEGV, si_utime=160, si_stime=31} ---
getpid()                                = 495
rt_sigreturn({mask=[]})                 = -1 EINTR (Interrupted system call)
wait4(-1, [{WIFSIGNALED(s) && WTERMSIG(s) == SIGSEGV && WCOREDUMP(s)}], WNOHANG, NULL) = 499
lseek(7, 0, SEEK_CUR)                   = 0
close(7)                                = 0
wait4(-1, 0x7ffd455ad844, WNOHANG, NULL) = 0
write(4, ".", 1)                        = 1
select(4, [3], [], [], {0, 450691})     = 1 (in [3], left {0, 450689})
read(3, ".", 1)                         = 1
read(3, 0x7f2682067de8, 1)              = -1 EAGAIN (Resource temporarily unavailable)
fstat(6, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(9, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(8, {st_mode=S_IFREG, st_size=0, ...}) = 0
umask(0)                                = 022
getpid()                                = 495
open("/tmp/wgunicorn-5x9a40ca", O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW|O_CLOEXEC, 0600) = 7
fcntl(7, F_SETFD, FD_CLOEXEC)           = 0
chown("/tmp/wgunicorn-5x9a40ca", 0, 0)  = 0
umask(022)                              = 0
unlink("/tmp/wgunicorn-5x9a40ca")       = 0
fstat(7, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
ioctl(7, TIOCGWINSZ, 0x7ffd455b8e50)    = -1 ENOTTY (Not a tty)
lseek(7, 0, SEEK_CUR)                   = 0
lseek(7, 0, SEEK_CUR)                   = 0
rt_sigprocmask(SIG_BLOCK, ~[], [], 8)   = 0
fork()                                  = 579
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
select(0, NULL, NULL, NULL, {0, 8144}[2017-12-28 17:50:30 +0000] [579] [INFO] Booting worker with pid: 579
)  = 0 (Timeout)
select(4, [3], [], [], {1, 0})          = 0 (Timeout)
fstat(6, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(7, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
fstat(9, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(8, {st_mode=S_IFREG|01, st_size=0, ...}) = 0

Estoy enfrentando el mismo problema, gunicorn se inicia repetidamente en segundos para el tipo de trabajador sync . Establecer el tiempo de espera del trabajador en 900 no ayuda.

En mi carga antes de la acción, estoy descargando datos de AWS S3. Se tarda aproximadamente 1 minuto y 10 segundos en descargar los distintos archivos.

@ sara-02 ¿cuál es tu línea de comando para lanzar gunicorn?

@benoitc gunicorn --pythonpath /src -b 0.0.0.0:$SERVICE_PORT --workers=1 -k sync -t $SERVICE_TIMEOUT flask_endpoint:app
Presente aquí

@ sara-02 Gracias.

¿Los trabajadores antiguos realmente están saliendo o se mantienen en línea y se generan nuevos trabajadores? ¿Qué muestra también el registro de depuración?

Los registros se mezclan con los registros de botocore, pero es algo como esto

[INFO] Booting worker with pid:  a
[INFO] Booting worker with pid:  b
[INFO] Booting worker with pid:  c

pero ¿el trabajador es asesinado? ¿Qué devuelve el comando ps ax|grep gunicorn ?

@benoitc
screenshot from 2018-07-05 19-14-00

Sin embargo, una pregunta, ¿por qué vemos 2 gunicorn procesos, cuando el límite de trabajadores se establece en 1? ¿Es un maestro y un trabajador?

Hay 1 proceso de árbitro (maestro) y N procesos de trabajo ye :)

Entonces, ejecuta el comando cada vez que un trabajador arranca, ¿verdad? Si es así, parece que el trabajador mayor muere, se genera uno nuevo. Yo investigaré.

@ sara-02 una última cosa, ¿esto también está sucediendo en Docker?

@benoitc en docker-compose está funcionando como se esperaba, pero cuando pongo el mismo código en Openshift , veo este error. El aumento del requisito de memoria se solucionó, pero cuando ejecuto la aplicación a través de docker-compose , está usando menos de limited memoria.

Solo una actualización, el problema para mí era en realidad un error de memoria y se solucionó cuando se solucionó el problema de memoria.

@benoitc
Estoy enfrentando el mismo problema al intentar generar 5 trabajadores gunicorn en Docker.
@ sara-02
¿Cómo identificaste la causa de un error de memoria?

image

@ gulshan-gaurav 2 cosas me ayudaron:
Aumenté la memoria asignada a mi Pod y dejé de fallar. En segundo lugar, verificamos nuestros registros de Openshift Zabbix.

@ sara-02
Incluso en mi Pod de ensayo, los archivos + modelos que estoy cargando en la memoria ascienden a 50 Mb, por lo que 2 GB de memoria deberían ser suficientes para 5 trabajadores.

@ gulshan-gaurav ¿a qué problema te enfrentas? Tener 5 procesos allí se ve bien ...

Tuve el mismo problema. No encontré el problema exacto, pero se resolvió una vez que actualicé de Python 3.5 a 3.6.

Estoy enfrentando el mismo problema en un contenedor Docker. Gunicorn sigue molestando a un nuevo trabajador cada vez que llamo a un punto final que causa la falla, pero no se genera una excepción o un error en los archivos de registro de Gunicorn. Las cosas que elijo imprimir se registran y, de repente, el archivo de registro dice "Arrancando trabajador con pid ..."

Un paso que ayudó fue agregar la variable env PYTHONUNBUFFERED. Antes de eso, incluso las declaraciones impresas desaparecerían y no se guardarían en los registros de Gunicorn.

Otros 2 puntos finales de la aplicación funcionan correctamente.

Ejecuto Gunicorn con: gunicorn run: app -b localhost: 5000 --enable-stdio-heritage --error-logfile /var/log/gunicorn/error.log --access-logfile / var / log / gunicorn / access. log --capture-output - depuración a nivel de registro

Ya está ejecutando Python 3.6 y comprobado con top que la memoria no parece ser un problema.

EDITAR: Parece que fue un problema de Python y no una culpa de Gunicorn. Algunas discrepancias de versiones estaban causando que Python simplemente muriera sin dejar rastro mientras realizaba una determinada operación.

Estoy enfrentando un problema similar en el que el nodo trabajador sigue apareciendo
Booting worker with pid: 17636 . No sé si está matando al nodo trabajador anterior o si aún existe un nodo trabajador anterior. Pero la cantidad de trabajadores mencionados en los argumentos de la línea de comandos de gunicorn es solo 3 - -workers=3 . También estoy usando Python versión 3.7

Tuve una falta de coincidencia de dependencia de scikit-learn, pero incluso después de resolver eso, sigo recibiendo los mismos trabajadores infinitos. ¿Qué tipo de discrepancias en la versión de Python debo buscar y cómo identificarlas?

Estoy enfrentando el mismo problema dentro de OpenShift.

image

Como puede ver en la imagen, estoy usando 6 trabajadores (estaba probando con 3).
Aumenté la memoria de la cápsula y no funcionó.

BuildConfig:

image

¿Alguna idea?

Gracias

¿estás ejecutando esto en aws detrás de elb? Resolví ese problema colocando el ingreso de nginx entre elb y gunicorn

Tiene el mismo problema.

flask_1  | [2019-02-23 09:08:17 +0000] [1] [INFO] Starting gunicorn 19.9.0
flask_1  | [2019-02-23 09:08:17 +0000] [1] [INFO] Listening at: http://0.0.0.0:5000 (1)
flask_1  | [2019-02-23 09:08:17 +0000] [1] [INFO] Using worker: sync
flask_1  | [2019-02-23 09:08:17 +0000] [8] [INFO] Booting worker with pid: 8
flask_1  | [2019-02-23 09:08:19 +0000] [12] [INFO] Booting worker with pid: 12
flask_1  | [2019-02-23 09:08:19 +0000] [16] [INFO] Booting worker with pid: 16
flask_1  | [2019-02-23 09:08:20 +0000] [20] [INFO] Booting worker with pid: 20
flask_1  | [2019-02-23 09:08:21 +0000] [24] [INFO] Booting worker with pid: 24
flask_1  | [2019-02-23 09:08:22 +0000] [28] [INFO] Booting worker with pid: 28
flask_1  | [2019-02-23 09:08:23 +0000] [32] [INFO] Booting worker with pid: 32
flask_1  | [2019-02-23 09:08:25 +0000] [36] [INFO] Booting worker with pid: 36
flask_1  | [2019-02-23 09:08:26 +0000] [40] [INFO] Booting worker with pid: 40
flask_1  | [2019-02-23 09:08:27 +0000] [44] [INFO] Booting worker with pid: 44
flask_1  | [2019-02-23 09:08:29 +0000] [48] [INFO] Booting worker with pid: 48
flask_1  | [2019-02-23 09:08:30 +0000] [52] [INFO] Booting worker with pid: 52
flask_1  | [2019-02-23 09:08:31 +0000] [56] [INFO] Booting worker with pid: 56
flask_1  | [2019-02-23 09:08:33 +0000] [60] [INFO] Booting worker with pid: 60
flask_1  | [2019-02-23 09:08:34 +0000] [64] [INFO] Booting worker with pid: 64
flask_1  | [2019-02-23 09:08:35 +0000] [68] [INFO] Booting worker with pid: 68
flask_1  | [2019-02-23 09:08:36 +0000] [72] [INFO] Booting worker with pid: 72
flask_1  | [2019-02-23 09:08:37 +0000] [76] [INFO] Booting worker with pid: 76
flask_1  | [2019-02-23 09:08:38 +0000] [80] [INFO] Booting worker with pid: 80
flask_1  | [2019-02-23 09:08:40 +0000] [84] [INFO] Booting worker with pid: 84
flask_1  | [2019-02-23 09:08:41 +0000] [88] [INFO] Booting worker with pid: 88
flask_1  | [2019-02-23 09:08:42 +0000] [92] [INFO] Booting worker with pid: 92
flask_1  | [2019-02-23 09:08:44 +0000] [96] [INFO] Booting worker with pid: 96
flask_1  | [2019-02-23 09:08:45 +0000] [100] [INFO] Booting worker with pid: 100
flask_1  | [2019-02-23 09:08:45 +0000] [104] [INFO] Booting worker with pid: 104
flask_1  | [2019-02-23 09:08:46 +0000] [108] [INFO] Booting worker with pid: 108
flask_1  | [2019-02-23 09:08:47 +0000] [112] [INFO] Booting worker with pid: 112
flask_1  | [2019-02-23 09:08:48 +0000] [116] [INFO] Booting worker with pid: 116
flask_1  | [2019-02-23 09:08:49 +0000] [120] [INFO] Booting worker with pid: 120
flask_1  | [2019-02-23 09:08:50 +0000] [124] [INFO] Booting worker with pid: 124
flask_1  | [2019-02-23 09:08:52 +0000] [128] [INFO] Booting worker with pid: 128

Aquí está docker-compose.yml :

version: '3'
services:
  flask:
    build: .
    command: gunicorn -b 0.0.0.0:5000 hello:app --reload
    environment:
      - FLASK_APP=hello.py
      - FLASK_DEBUG=1
      - PYTHONUNBUFFERED=True
    ports:
      - "5000:5000"
    volumes:
      - ./:/root

¿Qué imagen de Docker usa?

@benoitc

[ec2-user@ip-172-31-85-181 web-services-course]$ docker --version
Docker version 18.06.1-ce, build e68fc7a215d7133c34aa18e3b72b4a21fd0c6136
[ec2-user@ip-172-31-85-181 web-services-course]$ docker-compose --version
docker-compose version 1.23.2, build 1110ad01

Aquí están los enlaces para:

Descubrí que podría deberse a la falta de memoria. la aplicación necesita más memoria de la que está disponible.
pero es solo una suposición

Solo como información: había observado exactamente este comportamiento cuando tengo una configuración de gunicorn para 3 trabajadores, pero implementé el código en una máquina virtual con una CPU de un solo núcleo. Luego, cambio el entorno para usar 2 núcleos, y obviamente el problema desapareció

¿Por qué 'Trabajador sale' solo en el nivel INFO? ¿Por qué saldría un trabajador excepto como resultado de un error? Me tomó mucho tiempo darme cuenta de que el asesino de OOM del sistema estaba matando mis subprocesos de trabajo, sin nada en los registros excepto, como lo informaron algunos otros anteriormente, 'Arrancando trabajador con pid' de vez en cuando.

@HughWarrington porque la salida de un trabajador no es necesariamente un error. Los trabajadores pueden ser despedidos por señales o por opciones como --max-requests .

@HughWarrington , probablemente podríamos agregar el registro en el árbitro para cuando un trabajador sale con un código de salida anormal.

Puede abrir un boleto para eso o contribuir con un PR que agregue este código al método reap_workers .

Tuve el mismo problema y la solución fue aumentar el tamaño de la memoria del pod.

Tenía el mismo problema al ejecutar Gunicorn en Docker con un modelo de espacio grande, seguía reiniciando a los trabajadores sin ningún mensaje de error. La solución es aumentar la memoria del contenedor Docker.

Acabo de encontrar este problema hoy en el último gunicorn (19.9.0) con trabajadores gevent (1.4.0) que se ejecutan en Kubernetes. La aplicación es una aplicación de Falcon y la imagen de Docker es la imagen oficial de Python con la etiqueta 3.7.3 .

[2019-07-05 00:07:42 +0000] [8] [INFO] Starting gunicorn 19.9.0
[2019-07-05 00:07:42 +0000] [8] [INFO] Listening at: http://0.0.0.0:5000 (8)
[2019-07-05 00:07:42 +0000] [8] [INFO] Using worker: gevent
[2019-07-05 00:07:43 +0000] [35] [INFO] Booting worker with pid: 35
[2019-07-05 00:07:43 +0000] [36] [INFO] Booting worker with pid: 36
[2019-07-05 00:07:43 +0000] [37] [INFO] Booting worker with pid: 37
[2019-07-05 00:07:43 +0000] [38] [INFO] Booting worker with pid: 38
[2019-07-05 00:07:43 +0000] [41] [INFO] Booting worker with pid: 41
[2019-07-05 00:07:43 +0000] [43] [INFO] Booting worker with pid: 43
[2019-07-05 00:07:43 +0000] [45] [INFO] Booting worker with pid: 45
[2019-07-05 00:07:43 +0000] [49] [INFO] Booting worker with pid: 49
[2019-07-05 00:07:43 +0000] [47] [INFO] Booting worker with pid: 47
[2019-07-05 00:07:49 +0000] [53] [INFO] Booting worker with pid: 53
[2019-07-05 00:07:50 +0000] [54] [INFO] Booting worker with pid: 54
[2019-07-05 00:07:53 +0000] [57] [INFO] Booting worker with pid: 57
[...]

El pod tenía la siguiente configuración de recursos:

resources:
  requests:
    cpu: 250m
    memory: 256Mi
  limits:
    cpu: 500m
    memory: 512Mi

Duplicar todo solucionó el problema.

Una cosa interesante que notamos fue que cuando miramos dmesg en la máquina host podemos ver que está segfault -ing en libcrypto al acceder al servidor usando SSL

La memoria no parece ser un problema para mí porque no estoy cargando ningún modelo grande en la memoria. Los trabajadores siguen fallando y no veo ningún mensaje de error. ¿Hay alguna solución para esto?

image

mismo problema para mí, ¿alguna idea para solucionarlo? python 3.6.3 con gunicorn 19.9.0

@MrKiven, ¿ qué hace tu aplicación? ¿Estás usando cosas como request?

¿Alguien puede proporcionar una forma de reproducir el problema?

Es un administrador de varios componentes que se ejecutan en una tubería. Algunos de ellos pueden iniciar solicitudes HTTP a otros componentes en la misma máquina o en máquinas remotas. Algunos de los módulos de la canalización se pueden ejecutar en paralelo, pero se ejecutan mediante un ThreadPoolExecutor. No usan ningún objeto compartido, solo generan estructuras de datos que luego se agregan en un solo resultado.

Desafortunadamente, no estoy seguro de poder armar un ejemplo mínimo sin exponer el sistema que tenemos.

Las solicitudes hacen muchas cosas inseguras con subprocesos que a veces bifurcan un nuevo proceso. Aconsejaría utilizar otro cliente. ¿Puedes pegar al menos las líneas que estás usando para hacer una solicitud? ¿Está utilizando su función de tiempo de espera?

Uno de ellos podría ser:

try:
     resp = requests.post(self._endpoint, json=request_data)

     if resp.status_code != 200:
          logger.critical("[Error]: status code is {}".format(resp.status_code))
          return None

     response = resp.json()
     return {"intent": response["intent"], "intent_ranking": response["intent_ranking"]}
except ConnectionError as exc:
     logger.critical("[Exception] {}".format(str(exc)))
     return None

Gracias. Intentaré crear un sencillo a partir de él.

De todos modos, sería genial si alguien nos pudiera enviar un PR que reproduzca el comportamiento, ya sea como un ejemplo o una prueba unitaria para asegurarnos de que realmente estamos arreglando lo correcto.

No estoy seguro de si puede ayudar a alguien, pero tuve el mismo problema mientras ejecutaba una aplicación web de matraz dockerizado y lo resolví actualizando la imagen base de mi archivo docker a python:3.6.9-alpine

Dmesg en el host mostró un error de segmentación en lilibpython3.6m.so.1.0:

[626278.653010] gunicorn[19965]: segfault at 70 ip 00007f6423e7faee sp 00007ffc4e9a2a38 error 4 in libpython3.6m.so.1.0[7f6423d8a000+194000]

Mi imagen de la ventana acoplable se basó en python:3.6-alpine y estaba haciendo un apk update que estaba actualizando Python a 3.6.8.

Como dije, cambiar la imagen base a python:3.6.9-alpine resolvió para mí

Enfrenté el mismo desafío ejecutando un Flask + Docker + Kubernetes. El aumento de los límites de la CPU y la memoria lo resolvió para mí.

A nosotros nos pasó lo mismo. El aumento de los límites de recursos solucionó el problema.

Esto me sucedió de repente en macOS Catalina (no en contenedores).

Lo que me ayudó es:

  1. Instalación de openssl:
brew install openssl
  1. Ejecutando y agregando esto a mi ~/.zshrc :
export DYLD_LIBRARY_PATH=/usr/local/opt/openssl/lib:$DYLD_LIBRARY_PATH

Fuente: https://stackoverflow.com/a/58445755/5811984

Estoy teniendo un desafío similar y estaría agradecido si alguien pudiera ayudarme.
Esto es lo que tenía;

" root @ ubuntu-s-1vcpu-1gb-nyc1-01 : ~ # sudo systemctl status gunicorn.service ● gunicorn.service - demonio gunicorn Cargado: cargado (/etc/systemd/system/gunicorn.service; deshabilitado; preset del proveedor: habilitado) Activo: activo (en ejecución) desde Mon 2020-02-24 07:48:04 UTC; hace 44min PID principal: 4846 (gunicorn) Tareas: 4 (límite: 1151) CGroup: /system.slice/gunicorn.service ├ ─4846 / home / bright / djangoprojectdir / djangoprojectenv / bin / python / home / bright / djangoprojectdir / djangoprojectenv / bin / gunicorn - ├─4866 / home / bright / djangoprojectdir / djangoprojectenv / bin / python / home / bright / django / bin / gunicorn - ├─4868 / home / bright / djangoprojectdir / djangoprojectenv / bin / python / home / bright / djangoprojectdir / djangoprojectenv / bin / gunicorn - └─4869 / home / bright / djangoprojectdir / djangoprojectenv / bin / python / home / bright / djangoprojectdir / djangoprojectenv / bin / gunicorn - 24 de febrero 07:48:04 ubuntu-s-1vcpu-1gb-nyc1-01 systemd [1]: Detenido el demonio gunicorn. 24 de febrero 07:48:04 ubuntu-s-1vcpu -1gb-nyc1-01 systemd [1 ]: Inició el demonio gunicorn. 24 de febrero 07:48:05 ubuntu-s-1vcpu-1gb-nyc1-01 gunicorn [4846]: [2020-02-24 07:48:05 +0000] [4846] [INFO] Gunicorn inicial 20.0.4 24 de febrero 07:48:05 ubuntu-s-1vcpu-1gb-nyc1-01 gunicorn [4846]: [2020-02-24 07:48:05 +0000] [4846] [INFO] Escuchando en: unix: / run / gunicorn .soc 24 de febrero 07:48:05 ubuntu-s-1vcpu-1gb-nyc1-01 gunicorn [4846]: [2020-02-24 07:48:05 +0000] [4846] [INFO] Usando worker: sync Feb 24 07:48:05 ubuntu-s-1vcpu-1gb-nyc1-01 gunicorn [4846]: [2020-02-24 07:48:05 +0000] [4866] [INFO] Trabajador de arranque con pid: 4866 24 de febrero 07:48:05 ubuntu-s-1vcpu-1gb-nyc1-01 gunicorn [4846]: [2020-02-24 07:48:05 +0000] [4868] [INFO] Trabajador de arranque con pid: 4868 24 de febrero de 2007 : 48: 05 ubuntu-s-1vcpu-1gb-nyc1-01 gunicorn [4846]: [2020-02-24 07:48:05 +0000] [4869] [INFO] Trabajador de arranque con pid: 4869 24 de febrero 08: 03:41 ubuntu-s-1vcpu-1gb-nyc1-01 gunicorn [4846]: - - [24 / Feb / 2020: 08: 03: 41 +0000] "GET / HTTP / 1.0" 400 26 "-" "Mozilla /5.0 (Wi líneas 1-20 / 20 (FIN) "¿Alguien puede ayudarme a arreglar eso?

@BrightNana, ¿puedes intentar dar un dmesg y ver si tienes algún error de gunicorn?
dmesg | grep gunicorn podría ayudar a filtrar los otros errores

Hola,
Tengo el mismo error en debian 9 cuando quiero proporcionar gunicorn como un servicio systemd. Si lo inicio desde la CLI, gunicorn se ejecuta sin errores.

Extracto de dmesg | grep gunicorn :

Extracto de journalctl :
Mär 12 07:01:06 build-server gunicorn[828]: [2020-03-12 07:01:06 +0100] [1054] [INFO] Booting worker with pid: 1054 Mär 12 07:01:06 build-server gunicorn[828]: [2020-03-12 07:01:06 +0100] [1057] [INFO] Booting worker with pid: 1057 Mär 12 07:01:06 build-server gunicorn[828]: [2020-03-12 07:01:06 +0100] [1060] [INFO] Booting worker with pid: 1060 Mär 12 07:01:07 build-server gunicorn[828]: [2020-03-12 07:01:07 +0100] [1064] [INFO] Booting worker with pid: 1064 Mär 12 07:01:07 build-server gunicorn[828]: [2020-03-12 07:01:07 +0100] [1067] [INFO] Booting worker with pid: 1067 Mär 12 07:01:07 build-server gunicorn[828]: [2020-03-12 07:01:07 +0100] [1070] [INFO] Booting worker with pid: 1070 Mär 12 07:01:07 build-server gunicorn[828]: [2020-03-12 07:01:07 +0100] [1073] [INFO] Booting worker with pid: 1073 Mär 12 07:01:07 build-server gunicorn[828]: [2020-03-12 07:01:07 +0100] [1076] [INFO] Booting worker with pid: 1076 Mär 12 07:01:08 build-server gunicorn[828]: [2020-03-12 07:01:08 +0100] [1079] [INFO] Booting worker with pid: 1079 Mär 12 07:01:08 build-server gunicorn[828]: [2020-03-12 07:01:08 +0100] [1082] [INFO] Booting worker with pid: 1082 Mär 12 07:01:08 build-server gunicorn[828]: [2020-03-12 07:01:08 +0100] [1085] [INFO] Booting worker with pid: 1085 Mär 12 07:01:08 build-server gunicorn[828]: [2020-03-12 07:01:08 +0100] [1088] [INFO] Booting worker with pid: 1088 Mär 12 07:01:08 build-server gunicorn[828]: [2020-03-12 07:01:08 +0100] [1091] [INFO] Booting worker with pid: 1091 Mär 12 07:01:09 build-server gunicorn[828]: [2020-03-12 07:01:09 +0100] [1094] [INFO] Booting worker with pid: 1094
Extracto de systemctl status :
● api.service - API Server for BuildingChallenge served with Gunicorn Loaded: loaded (/etc/systemd/system/api.service; disabled; vendor preset: enabled) Active: active (running) since Thu 2020-03-12 08:26:01 CET; 22min ago Main PID: 8150 (gunicorn) Tasks: 3 (limit: 4915) Memory: 37.7M (high: 100.0M max: 500.0M) CGroup: /system.slice/api.service ├─ 8150 /opt/api/venv/bin/python /opt/api/venv/bin/gunicorn --bind unix:api.sock wsgi:app ├─28936 /opt/api/venv/bin/python /opt/api/venv/bin/gunicorn --bind unix:api.sock wsgi:app └─28938 /usr/bin/python3 -Es /usr/bin/lsb_release -a Mär 12 08:48:01 build-server gunicorn[8150]: [2020-03-12 08:48:01 +0100] [28909] [INFO] Booting worker with pid: 28909 Mär 12 08:48:01 build-server gunicorn[8150]: [2020-03-12 08:48:01 +0100] [28912] [INFO] Booting worker with pid: 28912 Mär 12 08:48:01 build-server gunicorn[8150]: [2020-03-12 08:48:01 +0100] [28915] [INFO] Booting worker with pid: 28915 Mär 12 08:48:01 build-server gunicorn[8150]: [2020-03-12 08:48:01 +0100] [28918] [INFO] Booting worker with pid: 28918 Mär 12 08:48:01 build-server gunicorn[8150]: [2020-03-12 08:48:01 +0100] [28921] [INFO] Booting worker with pid: 28921 Mär 12 08:48:01 build-server gunicorn[8150]: [2020-03-12 08:48:01 +0100] [28924] [INFO] Booting worker with pid: 28924 Mär 12 08:48:02 build-server gunicorn[8150]: [2020-03-12 08:48:02 +0100] [28927] [INFO] Booting worker with pid: 28927 Mär 12 08:48:02 build-server gunicorn[8150]: [2020-03-12 08:48:02 +0100] [28930] [INFO] Booting worker with pid: 28930 Mär 12 08:48:02 build-server gunicorn[8150]: [2020-03-12 08:48:02 +0100] [28933] [INFO] Booting worker with pid: 28933 Mär 12 08:48:02 build-server gunicorn[8150]: [2020-03-12 08:48:02 +0100] [28936] [INFO] Booting worker with pid: 28936

Gracias por tu ayuda.

Puse un PR que podría ayudar a depurar este tipo de situaciones. ¿Alguien puede echar un vistazo?
https://github.com/benoitc/gunicorn/pull/2315

Tuve el mismo problema con una aplicación Flask que se ejecuta dentro de Docker. Los trabajadores se reiniciaban infinitamente con un ID de proceso cada vez mayor.
image

El problema estaba relacionado con la memoria para mí, cuando aumenté la memoria permitida para Docker, los trabajadores se generaron de manera efectiva.
image

@tilgovi , no me importa si te gustaría incorporar mis cambios en tus relaciones públicas desde que llegaste primero. Esto cubrirá a los trabajadores que mueren a través de señales.

@mildebrandt Echaré un vistazo, ¡gracias!

También veo este comportamiento de repente, usando Gunicorn (20.0.4) + Gevent (1.5.0) + Flask dentro de un contenedor Docker.

[  328.699160] gunicorn[5151]: segfault at 78 ip 00007fc1113c16be sp 00007ffce50452a0 error 4 in _greenlet.cpython-37m-x86_64-linux-gnu.so[7fc11138d000+3e000]

En mi caso, como puede ver, el segfault está siendo causado por gevent. Lo extraño es que este contenedor funcionó bien hace 5 días, y ninguno de los cambios de código desde entonces cambió ninguna versión de ninguna de las bibliotecas, y todas están configuradas para versiones específicas. Eliminé flask-mail como dependencia, lo que puede haber alterado ligeramente las versiones de otras dependencias.

La actualización de gevent == 1.5.0 a gevent == 20.9.0 resolvió el problema por mí.

@ifiddes , es probable que su problema no esté relacionado. Está viendo un problema de compatibilidad ABI entre las versiones antiguas de gevent con la versión más reciente de greenlet. Ver https://github.com/python-greenlet/greenlet/issues/178

Ah, gracias @jamadden. Esta publicación fue todo lo que pude encontrar al buscar un desove infinito de trabajadores de arranque, pero ese problema y el momento en que se produjo se ajustan a mi problema.

Tuve un error similar con una nueva máquina AWS con Ubuntu 20.04 Server y con el mismo código que funciona en producción.

La máquina se configuró utilizando Ansible como las otras máquinas de producción.

[2020-10-15 15:11:49 +0000] [18068] [DEBUG] Current configuration:
  config: None
  bind: ['127.0.0.1:8000']
  backlog: 2048
  workers: 1
  worker_class: uvicorn.workers.UvicornWorker
  threads: 1
  worker_connections: 1000
  max_requests: 0
  max_requests_jitter: 0
  timeout: 30
  graceful_timeout: 30
  keepalive: 2
  limit_request_line: 4094
  limit_request_fields: 100
  limit_request_field_size: 8190
  reload: False
  reload_engine: auto
  reload_extra_files: []
  spew: False
  check_config: False
  preload_app: False
  sendfile: None
  reuse_port: False
  chdir: /var/www/realistico/app
  daemon: False
  raw_env: []
  pidfile: None
  worker_tmp_dir: None
  user: 1001
  group: 1001
  umask: 0
  initgroups: False
  tmp_upload_dir: None
  secure_scheme_headers: {'X-FORWARDED-PROTOCOL': 'ssl', 'X-FORWARDED-PROTO': 'https', 'X-FORWARDED-SSL': 'on'}
  forwarded_allow_ips: ['127.0.0.1']
  accesslog: /var/www/realistico/logs/gunicorn/access.log
  disable_redirect_access_to_syslog: False
  access_log_format: %(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"
  errorlog: /var/www/realistico/logs/gunicorn/error.log
  loglevel: debug
  capture_output: False
  logger_class: gunicorn.glogging.Logger
  logconfig: None
  logconfig_dict: {}
  syslog_addr: udp://localhost:514
  syslog: False
  syslog_prefix: None
  syslog_facility: user
  enable_stdio_inheritance: False
  statsd_host: None
  dogstatsd_tags: 
  statsd_prefix: 
  proc_name: None
  default_proc_name: realistico.asgi:application
  pythonpath: None
  paste: None
  on_starting: <function OnStarting.on_starting at 0x7f7ba5fdd550>
  on_reload: <function OnReload.on_reload at 0x7f7ba5fdd670>
  when_ready: <function WhenReady.when_ready at 0x7f7ba5fdd790>
  pre_fork: <function Prefork.pre_fork at 0x7f7ba5fdd8b0>
  post_fork: <function Postfork.post_fork at 0x7f7ba5fdd9d0>
  post_worker_init: <function PostWorkerInit.post_worker_init at 0x7f7ba5fddaf0>
  worker_int: <function WorkerInt.worker_int at 0x7f7ba5fddc10>
  worker_abort: <function WorkerAbort.worker_abort at 0x7f7ba5fddd30>
  pre_exec: <function PreExec.pre_exec at 0x7f7ba5fdde50>
  pre_request: <function PreRequest.pre_request at 0x7f7ba5fddf70>
  post_request: <function PostRequest.post_request at 0x7f7ba5f6e040>
  child_exit: <function ChildExit.child_exit at 0x7f7ba5f6e160>
  worker_exit: <function WorkerExit.worker_exit at 0x7f7ba5f6e280>
  nworkers_changed: <function NumWorkersChanged.nworkers_changed at 0x7f7ba5f6e3a0>
  on_exit: <function OnExit.on_exit at 0x7f7ba5f6e4c0>
  proxy_protocol: False
  proxy_allow_ips: ['127.0.0.1']
  keyfile: None
  certfile: None
  ssl_version: 2
  cert_reqs: 0
  ca_certs: None
  suppress_ragged_eofs: True
  do_handshake_on_connect: False
  ciphers: None
  raw_paste_global_conf: []
  strip_header_spaces: False
[2020-10-15 15:11:49 +0000] [18068] [INFO] Starting gunicorn 20.0.4
[2020-10-15 15:11:49 +0000] [18068] [DEBUG] Arbiter booted
[2020-10-15 15:11:49 +0000] [18068] [INFO] Listening at: unix:/run/gunicorn.sock (18068)
[2020-10-15 15:11:49 +0000] [18068] [INFO] Using worker: uvicorn.workers.UvicornWorker
[2020-10-15 15:11:49 +0000] [18080] [INFO] Booting worker with pid: 18080
[2020-10-15 15:11:49 +0000] [18068] [DEBUG] 1 workers
[2020-10-15 15:11:51 +0000] [18083] [INFO] Booting worker with pid: 18083
[2020-10-15 15:11:53 +0000] [18086] [INFO] Booting worker with pid: 18086
...
[2020-10-15 15:12:09 +0000] [18120] [INFO] Booting worker with pid: 18120
[2020-10-15 15:12:11 +0000] [18123] [INFO] Booting worker with pid: 18123

Después de mucho tiempo perdido tratando de resolver este problema sin éxito (y sin ningún error en los registros), lo intenté con este Hola mundo y encontré este error:

ModuleNotFoundError: No module named 'httptools'

Después de instalar httptools la aplicación Hello world funciona bien e, inesperadamente, también funciona mi aplicación.

No tengo idea de por qué no se registró el error o por qué esta biblioteca se instaló en las otras máquinas pero no en la nueva, pero esto solucionó el problema por mí.

Si esto sucediera recientemente y derribara el nodo de kubernetes en el que estaba consumiendo toda la CPU. Gracias a la pista sobre dmesg , finalmente encontré un error:

[225027.348869] traps: python[44796] general protection ip:7f8bd8f8f8b0 sp:7ffc21a0b370 error:0 in libpython3.7m.so.1.0[7f8bd8dca000+2d9000]

Al final, mi problema fue otra instancia de https://github.com/python-greenlet/greenlet/issues/178 y se resolvió actualizando gunicorn, gevent y greenlet a la última versión.

Dado que estos tipos de excepciones no crean registros de Python, no se pueden detectar, devuelven el código de salida 0 y pueden bloquear la máquina cuando ocurren, son bastante difíciles de administrar.

Propongo que Gunicorn detecte un bucle de choque rápido de esta naturaleza y

quizás max_consecutive_startup_crashes con el valor predeterminado num_workers * 10?

Rastreemos la solicitud de función de bucle de bloqueo en # 2504. También tenemos el RP para iniciar sesión adicional en # 2315. Cerraré este problema ya que parece que todos han depurado sus problemas y ahora tenemos algunas solicitudes de funciones y mejoras para ayudar a otros en el futuro. ¡Gracias a todos!

¿Fue útil esta página
0 / 5 - 0 calificaciones