Gunicorn: Tiempo de espera de los trabajadores de sincronización de Gunicorn en Docker + AWS

Creado en 29 ene. 2016  ·  78Comentarios  ·  Fuente: benoitc/gunicorn

Al usar gunicorn 19.4.5 dentro de una imagen de la ventana acoplable, que se ejecuta en Ubuntu 14.04 LTS en AWS, veo tiempos de espera de trabajador constantes cuando se ejecuta con> 1 trabajador de sincronización y el período de tiempo de espera predeterminado de 30 segundos. Esto puede estar relacionado con el n. ° 588 o con el n. ° 942, aunque esta es una versión significativamente más nueva de gunicorn, por lo que no podría estar seguro.

La evidencia circunstancial de varias ejecuciones parece sugerir que uno de los trabajadores no se ve afectado, y solo los trabajadores restantes N-1 son los que siguen fallando y reiniciando. Sin embargo, solo pude obtener algunos puntos de datos que sugieren esto, así que no lo tome como una señal fuerte.

Estas son las cosas que verifiqué:

  • ¿Los problemas ocurren fuera de la ventana acoplable o cuando se usa la misma imagen de la ventana acoplable, pero no en AWS?
    No, solo pude replicar el problema con Docker en AWS.
  • ¿La aplicación tarda más de 30 segundos en inicializarse?
    No, la aplicación termina de inicializarse en menos de 1 segundo.
  • ¿La aplicación recibe una solicitud que hace que se cuelgue?
    El problema apareció sin que se realizara ninguna solicitud a la aplicación.
  • ¿La aplicación tiene un código de inicialización roto que confunde a Gunicorn?
    El problema apareció al ejecutar gunicorn en la misma configuración (con> 1 trabajador de sincronización), pero con una aplicación diferente. Esta nueva aplicación se ejecuta sin problemas en gunicorn al utilizar gevent workers.
  • ¿El sistema de archivos de Docker no actualiza el ctime?
    Consulte el registro a continuación: el ctime generalmente parece avanzar bien. El sistema de archivos de Docker no permite stat -L en archivos eliminados, pero evitar que gunicorn desvincule el archivo también da como resultado que stat -L muestre que ctime se está actualizando como de costumbre.

Agregué un código a workertmp.py para registrar el tiempo de lectura en cada cheque, y aquí hay uno de esos registros (intercalado entre todos los trabajadores):

[2016-01-29 00:21:38 +0000] [3238] [INFO] Starting gunicorn 19.4.0
[2016-01-29 00:21:38 +0000] [3238] [INFO] Listening at: http://0.0.0.0:5000 (3238)
[2016-01-29 00:21:38 +0000] [3238] [INFO] Using worker: sync
[2016-01-29 00:21:38 +0000] [3243] [INFO] Booting worker with pid: 3243
[2016-01-29 00:21:38 +0000] [3244] [INFO] Booting worker with pid: 3244
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026899.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026899.03
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026900.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026899.03
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026900.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026899.03
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026900.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026899.03
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026900.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026899.03
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026904.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026899.03
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026904.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026905.0
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026904.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026905.0
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026904.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026905.0
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026904.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026905.0
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026904.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026909.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026910.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026909.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026910.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026909.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026910.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026909.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026910.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026909.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026933.73
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026934.74
FOOBAR: modify /tmp/wgun[2016-01-29 00:22:25 +0000] [3238] [CRITICAL] WORKER TIMEOUT (pid:3243)
[2016-01-29 00:22:25 +0000] [3243] [INFO] Worker exiting (pid: 3243)
[2016-01-29 00:22:25 +0000] [3330] [INFO] Booting worker with pid: 3330
icorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026935.0
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026935.0
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026935.0
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026935.0
FOOBAR: modify /tmp/wgunic54026934.74
FOOBAR: modify /tmp/wgun[2016-01-29 00:22:25 +0000] [3238] [CRITICAL] WORKER TIMEOUT (pid:3243)
[2016-01-29 00:22:25 +0000] [3243] [INFO] Worker exiting (pid: 3243)
[2016-01-29 00:22:25 +0000] [3330] [INFO] Booting worker with pid: 3330
icorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time:fy] [3238] [CRITICAL] WORKER TIMEOUT (pid:3243)
[2016-01-29 00p/2:25 +0000] [3243] [INFO] Worker exiting (pid: 3243)
[2016-0ic29 00:22:25 +0000] [3330] [INFO] Booting worker with pid: 33myicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorntiyjLwI time: 1454026935.0
FOOBAR: modify /tmp/wgunicorn-RhAFmt45ime: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026945.82
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026946.01
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026946.01
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026946.01
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8corn-myjLwI time:fy] [3238] [CRITICAL] WORKER TIMEOUT (pid:32BA)
[2016-01-29 00p/2:25 +0000] [3243] [INFO] Worker exiting (pdify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
FOOBAR: modify /tAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
FOOBAR: modify /tAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
FOOBAR: modify /tmp/wgunicorn-Mw64T1 timeodify /tmp/wgunicorn-myjLwI time: 1454026964.74
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026965.0
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026965.0
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026965.0
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026965.0
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026969.74
FOO[2016-01-29 00:22:59 +0000] [3238] [CRITICAL] WORKER TIMEOUT (pid:3330)
[2016-01-29 00:22:59 +0000] [3330] [INFO] Worker exiting (pid: 3330)
icorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026935.0
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026935.0
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026935.0
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026935.0
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026939.74
FOOBAR: modify /tmp/wgunicorn-LwI time: 1454026965.0
FOOBAR: modify /tmp/wgunicorn-Mw64T1 tI time: 1454026940.0
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026940.0
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026940.0
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026940.0
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026944.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
[2016-01-29 00:22:59 +0000] [3396] [INFO] Booting worker with pid: 3396
BAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026970.0
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026970.0
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjL26949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026970.0
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjL26949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026970.0
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjL26949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026970.0
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjL26949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026970.0
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjL26949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026970.0
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjL26949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026970.0
FOOBAR: modify /tmp/w79.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026979.97
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
80.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454029.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454029.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454029.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
 WORKER TIMEOUT (pid:3396)
 [2016-01-29 00:23:31 +0000] [3396] [INFO] Worker exiting (pid: 3396)
 BAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026970.0
 FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026970.0
 FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026970.0
 FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026970.0
 FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026974.74
 FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026975.0
 FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026975.0
 FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026975.0
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026975.0
 FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026975.0
 FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026975.0
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026975.0
 FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026975.0
 FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026975.0
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026975.0
 FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026975.0
 FOOBAR: modify /tmp/wgunicorn-Mw6nicorn-k3uZLy time: 1454026980.16
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027005.0
 FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027010.0
 FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027010.0
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027011.08
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027011.28
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027011.28
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027011.28
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmprn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmp/wgunicorn-Znicorn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027028.98
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027030.0
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027030.0
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wguicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027030.0
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027030.0
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wguicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027030.0
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027030.0
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wguicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027030.0
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn--ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027035.0
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /t[2016-01-29 00:24:05 +0000] [3238] [CRITICAL] WORKER TIMEOUT (pid:3453)
 [2016-01-29 00:24:05 +0000] [3453] [INFO] Worker exiting (pid: 3453)
FeaturIPC PlatforDocker - Bugs -

Comentario más útil

Intente usar los trabajadores gevent lugar, esto me ha resuelto el problema.

Todos 78 comentarios

hrmmm en el registro de arriba puedo ver que el tiempo nunca cambia. voy a ver

¡Gracias lo aprecio!

Puede que me afecte este error.

Estoy ejecutando gunicorn dentro de una imagen de Docker en AWS (Elastic Beanstalk + EC2 Container Service).
Hay tiempos de espera de trabajo constantes que comienzan a ocurrir casi inmediatamente después de la inicialización y solo cuando se ejecuta la imagen de Docker en AWS.
La misma solicitud HTTP tarda a veces unos pocos ms, a veces de 20 a 30 segundos. No importa si es para una página que no existe, una simple página de cadena de "Hola mundo" no autenticada o una página que obtiene registros de una base de datos.

Detalles adicionales :

  • Versiones de Gunicorn : 19.5.0 y 19.6.0.
  • Imagen base de Docker : python: 3.4 ( SO : Debian Jessie)
  • Versión de Docker : 1.9.1 (administrado por Amazon ECS), SO : Amazon Linux AMI 2016.03 (administrado por Amazon EB).
  • Marco de aplicación web : Django versiones 1.9.6 y 1.9.7.

Entornos _no_ afectados :

  • Máquina local , tanto _dentro_ como _fuera_ de un contenedor Docker. SO : Ubuntu 16.04 LTS, Docker : 1.11.2.
  • Heroku ( SO : Ubuntu 14.04 LTS)

Registros de contenedores de Amazon :

[2016-06-15 16:46:15 +0000] [1] [DEBUG] Current configuration:
  cert_reqs: 0
  post_request: <function PostRequest.post_request at 0x7fb13e187c80>
  worker_connections: 1000
  tmp_upload_dir: None
  enable_stdio_inheritance: False
  timeout: 30
  pre_fork: <function Prefork.pre_fork at 0x7fb13e1871e0>
  worker_int: <function WorkerInt.worker_int at 0x7fb13e1876a8>
  backlog: 2048
  max_requests: 0
  max_requests_jitter: 0
  access_log_format: %(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"
  logconfig: None
  syslog_addr: udp://localhost:514
  preload_app: False
  pidfile: None
  umask: 0
  secure_scheme_headers: {'X-FORWARDED-PROTOCOL': 'ssl', 'X-FORWARDED-PROTO': 'https', 'X-FORWARDED-SSL': 'on'}
  paste: None
  proxy_protocol: False
  worker_class: sync
  on_starting: <function OnStarting.on_starting at 0x7fb13e414c80>
  worker_abort: <function WorkerAbort.worker_abort at 0x7fb13e187840>
  worker_exit: <function WorkerExit.worker_exit at 0x7fb13e187e18>
  config: config/gunicorn.py
  nworkers_changed: <function NumWorkersChanged.nworkers_changed at 0x7fb13e18a048>
  daemon: False
  accesslog: None
  errorlog: -
  loglevel: debug
  syslog_prefix: None
  ssl_version: 3
  suppress_ragged_eofs: True
  limit_request_field_size: 8190
  reload: False
  logger_class: gunicorn.glogging.Logger
  statsd_host: None
  keyfile: None
  raw_env: []
  threads: 1
  django_settings: None
  proc_name: None
  proxy_allow_ips: ['127.0.0.1']
  limit_request_fields: 100
  ciphers: TLSv1
  check_config: False
  do_handshake_on_connect: False
  post_worker_init: <function PostWorkerInit.post_worker_init at 0x7fb13e187510>
  graceful_timeout: 30
  worker_tmp_dir: None
  certfile: None
  sendfile: None
  keepalive: 2
  chdir: /app/testapp
  when_ready: <function WhenReady.when_ready at 0x7fb13e187048>
  ca_certs: None
  on_exit: <function OnExit.on_exit at 0x7fb13e18a1e0>
  spew: False
  bind: [':8000']
  post_fork: <function Postfork.post_fork at 0x7fb13e187378>
  limit_request_line: 4094
  syslog_facility: user
  workers: 3
  syslog: False
  pre_request: <function PreRequest.pre_request at 0x7fb13e187b70>
  user: 0
  group: 0
  forwarded_allow_ips: ['127.0.0.1']
  pythonpath: None
  on_reload: <function OnReload.on_reload at 0x7fb13e414e18>
  pre_exec: <function PreExec.pre_exec at 0x7fb13e1879d8>
  default_proc_name: config.wsgi
  statsd_prefix: 
[2016-06-15 16:46:15 +0000] [1] [INFO] Starting gunicorn 19.5.0
[2016-06-15 16:46:15 +0000] [1] [DEBUG] Arbiter booted
[2016-06-15 16:46:15 +0000] [1] [INFO] Listening at: http://0.0.0.0:8000 (1)
[2016-06-15 16:46:15 +0000] [1] [INFO] Using worker: sync
[2016-06-15 16:46:15 +0000] [8] [INFO] Booting worker with pid: 8
[2016-06-15 16:46:15 +0000] [9] [INFO] Booting worker with pid: 9
[2016-06-15 16:46:15 +0000] [10] [INFO] Booting worker with pid: 10
[2016-06-15 16:46:15 +0000] [1] [DEBUG] 3 workers
[2016-06-15 16:46:52 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:9)
[2016-06-15 16:46:52 +0000] [9] [INFO] Worker exiting (pid: 9)
[2016-06-15 16:46:52 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:10)
[2016-06-15 16:46:52 +0000] [10] [INFO] Worker exiting (pid: 10)
[2016-06-15 16:46:53 +0000] [20] [INFO] Booting worker with pid: 20
[2016-06-15 16:46:53 +0000] [1] [DEBUG] 2 workers
[2016-06-15 16:46:53 +0000] [21] [INFO] Booting worker with pid: 21
[2016-06-15 16:46:53 +0000] [1] [DEBUG] 3 workers
[2016-06-15 16:47:23 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:8)
(...)

'

Gracias.

Yo también estoy viendo esto. Mi sospecha es el Elastic Load Balancer. Solíamos usar paste en una empresa anterior y esto estaba causando problemas con ELB. Creo que reutiliza las conexiones de alguna manera y esto estaba causando interrupciones en paste .

Ahora estoy en un nuevo trabajo en el que usamos gunicorn y todo estaba bien hasta que comenzamos a poner el servidor detrás de un ELB, la aplicación web ahora a menudo no responde y aparentemente se cuelga.

Intente usar los trabajadores gevent lugar, esto me ha resuelto el problema.

Entonces, ¿es esto un problema con el ELB manteniendo vivas las conexiones y atando al trabajador de sincronización? Eso me parecería muy extraño, ya que deliberadamente indicamos que la conexión debe cerrarse con el trabajador de sincronización: https://github.com/benoitc/gunicorn/blob/master/gunicorn/workers/sync.py#L168

Sin embargo, podríamos cerrar la conexión deliberadamente. Si alguien quiere probar mover la llamada client.close() para que sea incondicional, esa podría ser una prueba interesante: https://github.com/benoitc/gunicorn/blob/master/gunicorn/workers/sync.py#L199

También puede asegurarse de que el tiempo de espera inactivo en el ELB sea menor que el tiempo de espera del trabajador, como una verificación rápida de cordura de que esta es incluso la causa del problema: http://docs.aws.amazon.com/elasticloadbalancing/latest/ classic / config-idle-timeout.html

@tilgovi lo elb es mi mejor suposición actual, porque a) sucede solo si el gunicorn está detrás de un ELB yb) el problema se soluciona usando el trabajador gevent . Pero, de nuevo, quién sabe..

ocurre solo detrás de ELB, y si el protocolo HTTP o HTTPS está configurado en ELB.
Si cambia el protocolo a TCP o SSL, el problema desaparece.
¿Alguien sabe cómo solucionarlo usando trabajadores de sincronización? Usé la solución que describí (TCP en lugar de HTTP) hasta ahora, cuando voy a monitorear los registros de acceso y veré el encabezado X-Fordered-For, que está habilitado solo para HTTP / HTTPS en ELB :)

Es extraño, solo para asegurarnos de que estamos en la misma página, ¿esto significa que hay algún tipo de optimización al usar la opción HTTP / HTTPS en el ELB? ¿Y esta optimización está causando problemas con los trabajadores de sincronización?

@ecs Creo que, en el caso del balanceador de carga HTTP / HTTPS, reutilice la misma conexión TCP, que ELB mantiene activa durante mucho tiempo, una especie de eso. Pero no explica por qué gevent worker funciona bien ... (aunque todavía no he probado gevent, solo lea estos comentarios)

Por cierto, ciertamente hay muchos factores (versión gunicorn, clase de trabajador, dentro de la ventana acoplable o no, protocolo ELB) que pueden influir, por lo que sería genial si alguien probara y confirmara que el protocolo TCP en ELB funciona a diferencia de HTTP. Estoy probando en Docker alojado en Ubuntu 14.04 y gunicorn versión 19.3.0

Tengo el mismo problema:
[2016-10-03 12:13:17 +0000] [6] [CRÍTICO] TIEMPO DE MUERTE DEL TRABAJADOR (pid: 16)
[2016-10-03 12:13:17 +0000] [16] [INFO] Trabajador saliendo (pid: 16)
[2016-10-03 12:13:17 +0000] [6] [CRÍTICO] TIEMPO DE MUERTE DEL TRABAJADOR (pid: 20)
[2016-10-03 12:13:17 +0000] [20] [INFO] Trabajador saliendo (pid: 20)
[2016-10-03 12:13:17 +0000] [33] [INFO] Trabajador de arranque con pid: 33

Mi configuración.

Estoy usando kube-aws para configurar un clúster de kubernetes con core-os en AWS: https://github.com/coreos/coreos-kubernetes/tree/master/multi-node/aws

Tengo una aplicación de Python que usa gunicorn y trabajadores de sincronización. El servicio para ellos usa un balanceador de carga HTTPS con el certificado de mi sitio. Todos los trabajadores se consideran agotados después del tiempo de espera predeterminado de 30 segundos, según parece. Finalmente, todos se reinician. Kubernetes finalmente reinicia el contenedor cuando sale ... estos reinicios ocurren continuamente. Alguien mencionó anteriormente que gevent resuelve el problema. Puedo intentarlo, pero realmente me gustaría entender por qué está sucediendo esto.

También estamos viendo este problema actualmente, intentaré publicar más detalles cuando tenga la oportunidad. Está relacionado con el trabajador de sincronización, ya que pasar a gevent realmente resuelve el problema. Esto está en AWS con ECS y ELB.

También tuve el mismo problema extraño con una de nuestras aplicaciones. Cambiar los oyentes de HTTP a tcp resuelve el problema.

¿Alguien puede proporcionarme una forma paso a paso de reproducir el problema? (paso de configuración y demás) O al menos apúnteme a una forma sencilla de configurar ese entorno :) Lo echaré un vistazo esta semana.

Depender de HTTP para dicho equilibrador generalmente requiere manejar el mantenimiento de la vida detrás, (excepto para tcp), por lo que cualquier cosa que use un trabajador de sincronización puede ser un problema hasta que el trabajador de sincronización se actualice para su soporte.

De todos modos házmelo saber.

Simplemente configure una aplicación Flask básica y ejecútela con gunicorn con trabajadores de sincronización dentro de la ventana acoplable en AWS, con equilibrio de carga HTTP y la configuración de arriba:

Al usar gunicorn 19.4.5 dentro de una imagen de la ventana acoplable, que se ejecuta en Ubuntu 14.04 LTS en AWS, veo tiempos de espera de trabajador constantes cuando se ejecuta con> 1 trabajador de sincronización y el período de tiempo de espera predeterminado de 30 segundos.

No tiene que realizar ninguna solicitud a la aplicación, simplemente supervise los registros y verá que los trabajadores agotan el tiempo de espera.

  • Puedo confirmar este comportamiento, así como el enfoque básico para reproducirlo.

    • El comportamiento no se limita a Docker, sino a la configuración del trabajador de sincronización / keepalive, por lo que podría considerar cambiar el título ...

  • He modificado la configuración de keepalive para seguir lo que se describe aquí: https://serverfault.com/questions/782022/keepalive-setting-for-gunicorn-behind-elb-without-nginx/ (la parte más interesante es la cita de la documentación de AWS ELB) y descubrió que el servidor ya no mostraba este comportamiento.
  • Además, también he cambiado a la clase de trabajador gthread y he encontrado que el resultado es muy aceptable hasta ahora.

Actualmente estoy usando gevent trabajadores con un período de tiempo de espera de 65 segundos (el tiempo de espera de AWS ELB es de 60 segundos, AFAIK). A veces sigo experimentando errores 504 incluso cuando solo un cliente realiza solicitudes, con 1 solicitud en vuelo a la vez, pero todavía no pude precisar una razón.

@ obi1kenobi ¿

@lenucksi, el keepalive ya es más alto que el tiempo de espera de ELB en 5 segundos; con suerte, los relojes de los servidores no funcionan tanto :)

Yo también encontré este problema al ejecutar gunicorn 19.6 dentro de un contenedor Docker en una instancia EC2 detrás de un ELB (usando el protocolo HTTP predeterminado para el proxy inverso a la instancia EC2).

Como se sugirió anteriormente, configurar la clase de trabajador en gevent resolvió este problema para mí (donde anteriormente había estado usando la clase de trabajador predeterminada sync ).

Intentaré documentar un ejemplo mínimo para reproducir el problema.

Para corroborar lo que otros han dicho, el ELB parece estar abriendo una conexión con la instancia EC2 y manteniéndola abierta de una manera que bloquea a gunicorn para que no maneje solicitudes adicionales.

Cuando esa conexión mantenida abierta termina debido a que gunicorn agota el tiempo de espera de la solicitud del ELB, todas las solicitudes pendientes en cola detrás de él también fallan (incluida la verificación de estado del ELB, lo que hace que la instancia se elimine del ELB, lo que dificulta la depuración; )).

Este síntoma sugiere que se trata de un duplicado de lo observado en este número anterior que no está relacionado con Docker: https://github.com/benoitc/gunicorn/issues/588

@jelis ¿Sabes si esto está relacionado con alguna configuración de Kubernetes? ¿Se resolvió tu problema?

También estoy en un ELB con terminación SSL. Veo esto en mis registros:

[017-03-01 07:36:32 +0000] [1249] [DEBUG] GET /healthcheck
[01/Mar/2017:07:36:32 +0000] "GET /healthcheck HTTP/1.1" 200 22 "-" "ELB-HealthChecker/1.0"
[017-03-01 07:36:37 +0000] [12] [CRITICAL] WORKER TIMEOUT (pid:1203)
[017-03-01 07:36:37 +0000] [12] [CRITICAL] WORKER TIMEOUT (pid:1225)
[017-03-01 07:36:37 +0000] [12] [CRITICAL] WORKER TIMEOUT (pid:1234)
[017-03-01 07:36:37 +0000] [12] [CRITICAL] WORKER TIMEOUT (pid:1243)
[017-03-01 07:36:37 +0000] [1203] [INFO] Worker exiting (pid: 1203)
[017-03-01 07:36:37 +0000] [1225] [INFO] Worker exiting (pid: 1225)
[017-03-01 07:36:37 +0000] [1243] [INFO] Worker exiting (pid: 1243)
[017-03-01 07:36:37 +0000] [1234] [INFO] Worker exiting (pid: 1234)
[017-03-01 07:36:37 +0000] [1256] [INFO] Booting worker with pid: 1256
[017-03-01 07:36:37 +0000] [12] [DEBUG] 14 workers
[017-03-01 07:36:37 +0000] [1257] [INFO] Booting worker with pid: 1257
[017-03-01 07:36:37 +0000] [1262] [INFO] Booting worker with pid: 1262
[017-03-01 07:36:37 +0000] [1265] [INFO] Booting worker with pid: 1265
[017-03-01 07:36:37 +0000] [12] [DEBUG] 16 workers
[017-03-01 07:36:40 +0000] [1262] [DEBUG] GET /healthcheck

Actualización: acabo de cambiar de gunicorn a gevent (http://flask.pocoo.org/docs/0.12/deploying/wsgi-standalone/#gevent) y el problema está resuelto. Esto es en referencia a mi comentario anterior https://github.com/benoitc/gunicorn/issues/1194#issuecomment -283269046

He estado trabajando en este tema durante un par de días. Las notas de todos aquí son fantásticas y nos brindan una serie de vías para buscar soluciones / soluciones alternativas / mitigaciones. (el registro de mi trabajo está en el error que estamos rastreando aquí )

Intenté el uso de

[2017-03-30 23:38:37 +0000] [5] [INFO] Starting gunicorn 19.7.1
[2017-03-30 23:38:37 +0000] [5] [INFO] Listening at: http://0.0.0.0:8000 (5)
[2017-03-30 23:38:37 +0000] [5] [INFO] Using worker: eventlet
[2017-03-30 23:38:38 +0000] [8] [INFO] Booting worker with pid: 8
[2017-03-30 23:38:40 +0000] [9] [INFO] Booting worker with pid: 9
[2017-03-30 23:38:41 +0000] [11] [INFO] Booting worker with pid: 11
[2017-03-30 23:38:42 +0000] [12] [INFO] Booting worker with pid: 12
[2017-03-30 23:38:42 +0000] [10] [INFO] Booting worker with pid: 10
[2017-03-30 23:40:08 +0000] [5] [CRITICAL] WORKER TIMEOUT (pid:8)
[2017-03-30 23:40:12 +0000] [5] [CRITICAL] WORKER TIMEOUT (pid:9)
[2017-03-30 23:40:12 +0000] [5] [CRITICAL] WORKER TIMEOUT (pid:10)
[2017-03-30 23:40:12 +0000] [5] [CRITICAL] WORKER TIMEOUT (pid:11)
[2017-03-30 23:40:12 +0000] [5] [CRITICAL] WORKER TIMEOUT (pid:12)
[2017-03-30 23:40:13 +0000] [8] [INFO] Worker exiting (pid: 8)
[2017-03-30 23:40:13 +0000] [10] [INFO] Worker exiting (pid: 10)
[2017-03-30 23:40:16 +0000] [16] [INFO] Booting worker with pid: 16
[2017-03-30 23:40:16 +0000] [17] [INFO] Booting worker with pid: 17
[2017-03-30 23:40:18 +0000] [18] [INFO] Booting worker with pid: 18
[2017-03-30 23:40:20 +0000] [19] [INFO] Booting worker with pid: 19
[2017-03-30 23:40:23 +0000] [20] [INFO] Booting worker with pid: 20

Es probable que esto sea un error de mi parte, y no fue el mismo comportamiento que uno de mis contrapartes del proyecto (con una base de código similar pero no idéntica en una implementación de AWS / CloudFormation / ALB / ECS casi idéntica). Sin embargo, pensé que lo reportaría en caso de que inspire nuevos conocimientos sobre las interacciones entre ALB, ECS, Docker y gunicorn.

Tengo una configuración similar (convox ejecutando ELB-> ECS Docker Container-> Gunicorn-> Django) y puedo confirmar que los siguientes cambios de configuración parecen haber ayudado:

keepalive = 75 # needs to be longer than the ELB idle timeout
timeout = 90
worker_class = 'gevent'

Configuré el tiempo de espera inactivo de mi ELB en 60 segundos.

Antes de cambiar esta configuración, estaba usando los valores predeterminados para keepalive, timeout y sync worker.

Curiosamente, este problema comenzó a aparecer a las 4 am UTC del 10 de abril. La aplicación había estado funcionando bien sin ningún cambio desde el jueves anterior.

simplemente acumulando, sin ventana acoplable, pero la instancia de aws desnuda estaba teniendo el mismo problema detrás de un ELB. funciona NP en osx, pero ubuntu16 con un ELB mismo problema surgió. gevent clase de trabajador

@erikcw parece haber encontrado que esta solución funciona. Me gustaría cerrar este problema. Si alguien puede reproducir esto después de aumentar el tiempo de espera del trabajador Gunicorn y el tiempo de espera activo, dígalo.

Alternativamente, reduzca el tiempo de espera inactivo para ELB.

¿No podría un cliente en la naturaleza (o un cliente infame) actuar como ELB y causar el mismo problema?

@ six8 sí. ELB tampoco te protege de esto. La documentación analiza esto: http://docs.gunicorn.org/en/latest/design.html#choosing -a-worker-type

A algunas personas no les importa esta amenaza y solo quieren desplegar Gunicorn, en el borde o detrás de un ELB. El problema que se analiza aquí son los tiempos de espera de los trabajadores provocados por el propio ELB. Me gustaría proporcionar la configuración recomendada que hace que gunicorn funcione detrás de ELB con trabajadores de sincronización y sin un proxy inverso adicional.

Probé @erikcw solución 's, así cambiando la invocación gunicorn a:

CMD [ "gunicorn", "-k", "gevent", "--timeout", "10", "--keep-alive", "75", "--paste", "/etc/jzoo/app.ini" ]

Desafortunadamente eso no ayuda:

[2017-07-04 08:36:23 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:24)
[2017-07-04 08:38:11 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:28)
[2017-07-04 08:39:39 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:29)
[2017-07-04 08:44:14 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:25)
[2017-07-04 08:44:55 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:31)

Tengo una aplicación que se ejecuta en ECS detrás de un ALB con trabajadores de sincronización de Gunicorn. Todavía no he visto ningún problema.

¿Alguien puede proporcionar una implementación reproducible?

amontonando, también. viendo este problema al usar Kubernetes en AWS con ELB. Actualmente tenemos 8 trabajadores funcionando. Según https://serverfault.com/questions/782022/keepalive-setting-for-gunicorn-behind-elb-without-nginx/ , subiremos keepalive , y según este hilo vamos a intentar para usar gevent trabajadores en su lugar. Pero en este momento, lo que está fallando son algunas pruebas de rendimiento para llamadas de API que no deberían bloquear / causar tiempos de espera por sí solas. quisiera saber qué está pasando aquí con sync trabajadores. incluso si logramos que esto funcione según algunas de las buenas pautas de este hilo, nos gustaría tener un poco más de confianza en cuanto a lo que está sucediendo antes de implementarlo en producción.

Establecer la --worker-class en --worker-class gevent funcionó para mí. ¡Gracias por los comentarios y ayuda!

@wichert esto es muy extraño. Con el trabajador gevent, los trabajadores deben notificar al árbitro de su nivel de vida en un greenlet separado de cualquier conexión. Su configuración de mantener vivo no debería afectar esto en absoluto. Algo está mal con su aplicación, de modo que gevent no está funcionando como se diseñó, o algo en la configuración es problemático que podría ser común en estos otros escenarios.

Por favor, todos en este hilo, proporcionen una aplicación que reproduzca este problema. No he podido reproducirlo. Sin pasos para reproducir, estoy tentado a cerrar. Hay una combinación de recomendaciones y tal vez temas muy diferentes enterrados en estos comentarios. Es difícil saber qué hacer con este problema.

@tilgovi Experimenté este problema cuando no especificaba la clase de trabajador para gevent (por ejemplo, usando el trabajador de sincronización predeterminado). Mi configuración es virtualenv usando pypy3 (PyPy 5.8.0-beta0), falcon 1.2, etc. (entender que Falcon no es oficialmente compatible con pypy3). Usé el cortador de galletas de https://github.com/7ideas/cookiecutter-falcon y actualicé a todos los paquetes más recientes y al intentar cargar sample_resource en el navegador y presionarlo muchas veces con http: vería intermitentemente el error de bloqueo del trabajador ( por ejemplo, la solicitud se retrasaría y luego vería el error; si no cancelaba la solicitud, eventualmente respondería). Esto solo sucedió con la clase de trabajador predeterminada de sincronización. Cuando lo especifiqué para usar gevent, todo funcionó.

Gracias, @ jhillhouse92 , lo intentaré.

Sigo viendo problemas con los tiempos de espera, @tilgovi. Estaré solucionando este problema más mañana y publicaré una actualización con información más precisa. Por favor, mantenga este problema abierto; tiene razón en que puede haber una variedad de problemas, pero el tema general es que los trabajadores de gunicorn (tal vez solo con la clase de trabajador de sincronización, tbd) tienen problemas de tiempo de espera cuando usan gunicorn con una aplicación implementada usando AWS / ELB. Hay algo mal aquí, incluso si no hemos aislado el problema exacto. Vale la pena investigar más. Lo actualizaré mañana.

Vale la pena señalar que experimenté este problema localmente, no dentro de Docker / AWS / ELB con la pila anterior que mencioné.

Entonces estoy usando gevent, tratando de capturar mis registros de acceso y tratando de implementar mi aplicación usando AWS / ELB.

comandos de dockerfile:

FROM cortex/base

CMD ["gunicorn", "-w", "8", "-b", "0.0.0.0:5000", "--capture-output", "--enable-stdio-inheritance", "--access-logfile", "-", "--worker-class", "gevent", "-t", "60", "--log-level", "debug", "app:app"]

Recibo errores de OOM locos en relación con el código de error 14, independientemente de a qué establezca los límites. ¿Alguien más ha visto esto en el contexto de este problema? Anteriormente, podía ver los tiempos de espera de los trabajadores. Con mis configuraciones actuales, no puedo reproducir los tiempos de espera / llegar tan lejos.

[2017-07-19 18:27:39 +0000] [34] [ERROR] Exception in worker process
Traceback (most recent call last):
  File "/usr/local/lib/python3.5/site-packages/gunicorn/arbiter.py", line 578, in spawn_worker
    worker.init_process()
  File "/usr/local/lib/python3.5/site-packages/gunicorn/workers/ggevent.py", line 190, in init_process
    super(GeventWorker, self).init_process()
  File "/usr/local/lib/python3.5/site-packages/gunicorn/workers/base.py", line 126, in init_process
    self.load_wsgi()
  File "/usr/local/lib/python3.5/site-packages/gunicorn/workers/base.py", line 135, in load_wsgi
    self.wsgi = self.app.wsgi()
  File "/usr/local/lib/python3.5/site-packages/gunicorn/app/base.py", line 67, in wsgi
    self.callable = self.load()
  File "/usr/local/lib/python3.5/site-packages/gunicorn/app/wsgiapp.py", line 65, in load
    return self.load_wsgiapp()
  File "/usr/local/lib/python3.5/site-packages/gunicorn/app/wsgiapp.py", line 52, in load_wsgiapp
    return util.import_app(self.app_uri)
  File "/usr/local/lib/python3.5/site-packages/gunicorn/util.py", line 376, in import_app
    __import__(module)
  File "/code/app/__init__.py", line 2, in <module>
    from flask_alchy import Alchy
  File "/usr/local/lib/python3.5/site-packages/flask_alchy.py", line 8, in <module>
    from flask_sqlalchemy import SQLAlchemy
  File "/usr/local/lib/python3.5/site-packages/flask_sqlalchemy/__init__.py", line 18, in <module>
    import sqlalchemy
  File "/usr/local/lib/python3.5/site-packages/sqlalchemy/__init__.py", line 9, in <module>
    from .sql import (
  File "/usr/local/lib/python3.5/site-packages/sqlalchemy/sql/__init__.py", line 8, in <module>
    from .expression import (
  File "/usr/local/lib/python3.5/site-packages/sqlalchemy/sql/expression.py", line 34, in <module>
    from .functions import func, modifier, FunctionElement, Function
  File "/usr/local/lib/python3.5/site-packages/sqlalchemy/sql/functions.py", line 11, in <module>
    from . import sqltypes, schema
  File "<frozen importlib._bootstrap>", line 969, in _find_and_load
  File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 658, in exec_module
  File "<frozen importlib._bootstrap_external>", line 763, in get_code
  File "<frozen importlib._bootstrap_external>", line 816, in get_data
OSError: [Errno 14] Bad address

Para reiterar, no veo esto localmente sin Docker. No veo esto localmente con Docker. Esto, y los problemas de tiempo de espera, solo se vuelven aparentemente en la pila Docker / AWS / ELB (para mí).

@tilgovi Una cosa que inicialmente hice mal (como se puede ver en el fragmento que publiqué arriba) es que tenía el tiempo de espera configurado incorrectamente en 10 segundos. Después de cambiar eso a 75 segundos, el número de tiempos de espera de los trabajadores se redujo significativamente a quizás un par por día. Para completar, este es el comando exacto que estoy usando para iniciar nuestra aplicación:

gunicorn -k gevent --timeout 90 --keep-alive 75 --paste /etc/jzoo/app.ini "$@"

El archivo .ini tiene este aspecto:

[DEFAULT]
sqlalchemy.url = postgresql://XXXX

[app:main]
use = egg:jzoo.api.admin

[server:main]
use = egg:gunicorn#main
bind = 0.0.0.0:5000
workers = 4
preload_app = true
loglevel = warning

# Logging configuration
[loggers]
keys = root,sqlalchemy,alembic,jzoo

# .. more logging configuration

La cantidad de tráfico no parece ser un factor; veo que esto sucede en nuestro entorno de control de calidad, que solo ve muy poco tráfico.

Mirando con qué frecuencia sucede esto, me pregunto si esto podría estar relacionado con el reinicio de la aplicación.

Tengo un problema algo similar. Después de algunas investigaciones, creo que probablemente sea un error de conexión de red, no de Gunicorn.

Aquí está mi configuración:

  • El servidor Postgresql se ejecuta en Docker en EC2. La imagen de la ventana acoplable es la versión oficial de postgres 9.6.
  • El servidor de aplicaciones se ejecuta en Docker en una máquina virtual fuera de EC2. La imagen de la ventana acoplable es la versión oficial de Python 3.6.
  • Solo el puerto 5432 / tcp está abierto en el grupo de seguridad de AWS.

Curiosamente, la mayoría de las solicitudes del servidor de aplicaciones al servidor de Postgres estaban bien, excepto una. Esa consulta parece durar para siempre, lo que agota el tiempo de espera del trabajador gunicorn.

El problema desaparece si utilizo la aplicación localmente.

El problema también desaparece si no dockerizo el servidor de aplicaciones.

Mi solución temporal es abrir todas las conexiones entre el servidor de aplicaciones y el servidor de Postgres a través de la configuración del grupo de seguridad de AWS. Ahora todo vuelve a funcionar correctamente.

Supongo que hay un problema de conexión entre el contenedor de Python y AWS. Actualizaré después de examinar detenidamente el flujo de registros de AWS.

¡¡Gracias!! Cambiar ELB y el protocolo de instancia de HTTP a TCP funcionó bien 👍

El problema no parece específico de AWS, sino del propio Docker cuando se combina con Gunicorn. También veo esto con gevent , al menos en nuestro entorno de producción.

@tilgovi Aquí hay una aplicación simple para recrear este error (de vez en cuando, no he encontrado el patrón, tal vez podría hacerlo):

app.py:

import falcon


class HelloResource:
    def on_get(self, req, resp):
        resp.media = {'info': 'hello world'}


app = falcon.API()
app.add_route('/', HelloResource())

Dockerfile:

FROM python:3.6
WORKDIR /code
RUN pip install gunicorn falcon
COPY app.py .
CMD ["gunicorn", "app:app", "--bind", "0.0.0.0:8000"]

Para ejecutar: docker build -t gunicorn-and-docker . && docker run -p 8000:8000 -it --rm gunicorn-and-docker

Los registros se verán así (al menos para mí en macOS Sierra usando Docker 17.06.2-ce-mac27 (19124)):

[2017-09-23 22:31:00 +0000] [1] [INFO] Starting gunicorn 19.7.1
[2017-09-23 22:31:00 +0000] [1] [INFO] Listening at: http://0.0.0.0:8000 (1)
[2017-09-23 22:31:00 +0000] [1] [INFO] Using worker: sync
[2017-09-23 22:31:00 +0000] [9] [INFO] Booting worker with pid: 9
[2017-09-23 23:22:45 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:9)
[2017-09-23 23:22:45 +0000] [9] [INFO] Worker exiting (pid: 9)
[2017-09-23 23:22:45 +0000] [11] [INFO] Booting worker with pid: 11
[2017-09-23 23:39:46 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:11)
[2017-09-23 23:39:46 +0000] [11] [INFO] Worker exiting (pid: 11)
[2017-09-23 23:39:46 +0000] [13] [INFO] Booting worker with pid: 13
[2017-09-23 23:41:10 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:13)
[2017-09-23 23:41:10 +0000] [13] [INFO] Worker exiting (pid: 13)
[2017-09-23 23:41:10 +0000] [15] [INFO] Booting worker with pid: 15
[2017-09-23 23:42:27 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:15)
[2017-09-23 23:42:27 +0000] [15] [INFO] Worker exiting (pid: 15)
[2017-09-23 23:42:27 +0000] [17] [INFO] Booting worker with pid: 17
[2017-09-23 23:43:44 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:17)
[2017-09-23 23:43:44 +0000] [17] [INFO] Worker exiting (pid: 17)
[2017-09-23 23:43:44 +0000] [19] [INFO] Booting worker with pid: 19
[2017-09-24 18:37:12 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:19)
[2017-09-24 18:37:12 +0000] [19] [INFO] Worker exiting (pid: 19)
[2017-09-24 18:37:12 +0000] [21] [INFO] Booting worker with pid: 21
[2017-09-24 19:49:20 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:21)
[2017-09-24 19:49:20 +0000] [21] [INFO] Worker exiting (pid: 21)
[2017-09-24 19:49:20 +0000] [23] [INFO] Booting worker with pid: 23
[2017-09-24 19:50:37 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:23)
[2017-09-24 19:50:37 +0000] [23] [INFO] Worker exiting (pid: 23)
[2017-09-24 19:50:37 +0000] [25] [INFO] Booting worker with pid: 25
[2017-09-24 20:25:48 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:25)
[2017-09-24 20:25:48 +0000] [25] [INFO] Worker exiting (pid: 25)
[2017-09-24 20:25:48 +0000] [27] [INFO] Booting worker with pid: 27

Hola,

Recientemente me encontré con el mismo problema.
En mi caso (ECS + gunicorn 19.7.1 + Django 1.11.5) logré (aparentemente) resolverlo simplemente aumentando la cantidad de memoria dedicada al contenedor en la definición de la tarea (de 128 a 256mb).
No más errores hasta ahora. Informaré aquí si vuelve a suceder.

Añadiendo un poco al coro aquí, pero pude resolver esto solo cambiando a gevent.

Traté de aumentar el tiempo de espera a 90 y mantener vivo a 75 con el trabajador de sincronización sin suerte.

Además, curiosamente, mi ELB en este escenario solo está haciendo reenvío de nivel TCP y no HTTP.

De acuerdo, encontré algunas referencias que explican esto. [1]

Podría resolverse con pequeños cambios en el lado de Gunicorn. Si, en el trabajador de sincronización, después de aceptar una nueva conexión, llamamos a select() con un breve tiempo de espera, entonces podríamos manejar estas conexiones. Podría complicarse un poco, especialmente con varias tomas de escucha. Lo más simple sería tener un tiempo de espera para el primer byte. Tampoco estoy seguro de cómo interactuaría eso con SSL.

[1] https://cloudavail.com/2013/12/21/aws-elb-pre-open-connection-expose-part-1/

Si está experimentando esto y no desea usar gevent / eventlet / asyncio, le recomiendo que cambie al trabajador con subprocesos (proporcione la configuración --threads ).

@tilgovi El problema parece existir también con gevent worker, si miras mi ejemplo anterior.

@jmagnusson su ejemplo (de este comentario: https://github.com/benoitc/gunicorn/issues/1194#issuecomment-331740187) parece estar usando el trabajador de sincronización.

[2017-09-23 22:31:00 +0000] [1] [INFO] Usando trabajador: sincronización

@tilgovi Cierto, pero también he experimentado esto con el trabajador gevent en producción. Intentaré encontrar algo de tiempo para reproducirme con Gevent.

Este puede ser solo yo (tonto), pero en el grupo de seguridad EC2 -> reglas de entrada, tengo una regla TCP personalizada para el puerto 5000 (gunicorn aquí) para permitir solo una única IP (mi IP: XX.XX.XX.XX / 32), cambiar esto a todas las IP ayudará.

Yo también me encuentro con el problema.

[2018-01-02 16:38:03 +0800] [24355] [INFO] Starting gunicorn 19.7.1
[2018-01-02 16:38:03 +0800] [24355] [DEBUG] Arbiter booted
[2018-01-02 16:38:03 +0800] [24355] [INFO] Listening at: http://0.0.0.0:8080 (24355)
[2018-01-02 16:38:03 +0800] [24355] [INFO] Using worker: gevent
[2018-01-02 16:38:03 +0800] [24358] [INFO] Booting worker with pid: 24358
[2018-01-02 16:38:03 +0800] [24355] [DEBUG] 1 workers
[2018-01-02 16:38:03 +0800] [24358] [INFO] worker pid 24358 notify
[2018-01-02 16:38:04 +0800] [24358] [INFO] worker pid 24358 notify
[2018-01-02 16:38:05 +0800] [24358] [INFO] worker pid 24358 notify
[2018-01-02 16:38:06 +0800] [24358] [INFO] worker pid 24358 notify
[2018-01-02 16:38:07 +0800] [24358] [INFO] worker pid 24358 notify
[2018-01-02 16:38:08 +0800] [24358] [INFO] worker pid 24358 notify
[2018-01-02 16:38:09 +0800] [24358] [INFO] worker pid 24358 notify
[2018-01-02 16:38:10 +0800] [24358] [INFO] worker pid 24358 notify
[2018-01-02 16:38:10 +0800] [24358] [DEBUG] GET /v1/bj2/CC/uuid
[2018-01-02 16:38:10 +0800] [24358] [DEBUG] Closing connection. 
[2018-01-02 16:38:41 +0800] [24355] [CRITICAL] WORKER TIMEOUT (pid:24358)
[2018-01-02 16:38:41 +0800] [24358] [INFO] Worker exiting (pid: 24358)
[2018-01-02 16:38:41 +0800] [24381] [INFO] Booting worker with pid: 24381
[2018-01-02 16:38:41 +0800] [24381] [INFO] worker pid 24381 notify
[2018-01-02 16:38:42 +0800] [24381] [INFO] worker pid 24381 notify
[2018-01-02 16:38:43 +0800] [24381] [INFO] worker pid 24381 notify
[2018-01-02 16:38:44 +0800] [24381] [INFO] worker pid 24381 notify
[2018-01-02 16:38:45 +0800] [24381] [INFO] worker pid 24381 notify
[2018-01-02 16:38:46 +0800] [24381] [INFO] worker pid 24381 notify
[2018-01-02 16:38:47 +0800] [24381] [INFO] worker pid 24381 notify
......
[2018-01-02 16:48:20 +0800] [24381] [INFO] worker pid 24381 notify
[2018-01-02 16:48:51 +0800] [24355] [CRITICAL] WORKER TIMEOUT (pid:24381)
[2018-01-02 16:48:51 +0800] [24381] [INFO] Worker exiting (pid: 24381)
[2018-01-02 16:48:51 +0800] [24703] [INFO] Booting worker with pid: 24703
[2018-01-02 16:48:51 +0800] [24703] [INFO] worker pid 24703 notify
[2018-01-02 16:48:51 +0800] [24703] [DEBUG] GET /v1/bj2/CC/uuid
[2018-01-02 16:48:51 +0800] [24703] [DEBUG] Closing connection. 

Agregué el registro de depuración worker pid {WORKER_PID} notify .

Según el registro de depuración,

  1. Solo si el proceso de trabajo recibe una solicitud, la notificación no continuará. Entonces, ya sea que haya solicitudes o no, el maestro eliminará el proceso de trabajo después de 30 segundos.
  2. Una vez que se cerró la primera solicitud, envié la segunda solicitud en este momento, pero la segunda solicitud está bloqueada y no hay respuesta. Cuando se alcanzó el tiempo de espera de 30 segundos, el proceso de trabajo se eliminó y el nuevo proceso de trabajo respondería la segunda solicitud. Luego, el servidor se ha colgado nuevamente.
  3. Cuando el proceso de trabajo se ha colgado, no recibiría la señal del maestro, como SIGTERM . Cuando llegaba el tiempo de espera elegante, el maestro lo mataba SIGKILL coercitiva.
Python: 3.6.3
Gevent: 1.2.2
Gunicorn: 19.7.1
RUN CMD: gunicorn --worker-class gevent --log-level debug --bind 0.0.0.0:8080 app

AVISO: Cuando uso eventlet como trabajador, está bien.

Voy a cerrar este tema porque creo que está un poco desactualizado. Lo mejor que pude determinar, el comportamiento observado se debe a que AWS Classic Load Balancers realiza una optimización preabierta. Esta optimización solo la realizan Classic Load Balancers, de acuerdo con la documentación sobre cómo funciona el balanceo de carga . El cambio a Application Load Balancers debería resolver el problema. Además, como se documenta en esta publicación de blog , es posible solicitar a AWS que desactive la optimización previa a la apertura o que aumente el tiempo de espera del trabajador para Gunicorn.

@tilgovi FWIW Vi esto con ALB. Nunca he usado equilibradores de carga clásicos.

@tilgovi Yo también observé esto repetidamente en entornos solo de ALB, sin haber usado nunca clásico. Incluso con los ajustes del tiempo de espera de los trabajadores, seguimos viendo esto.

@tilgovi me encontré con esto. Nunca he usado AWS.

Alguien tiene que ayudar a reproducir esto, entonces, e intentar depurarlo. No puedo reproducirlo con ALB y no veo cómo reproducirlo fuera de AWS.

@xgfone, es posible que desee abrir su propio problema, el título de este problema es "Docker + AWS"

¿Alguien experimentó esto con los balanceadores de carga de AWS pero sin Docker? Estoy un poco confundido, tengo que admitir :)

Mi impresión fue que el problema estaba realmente más relacionado con Docker; al menos tuve exactamente los mismos problemas al ejecutar varios trabajadores de sincronización de gunicorn dentro de Docker en mi máquina local.

Esta configuración funcionó bien sin Docker en máquinas Ubuntu y RHEL, tanto bare metal como virtualizadas en Digital Ocean:

workers = 2
worker_class = 'sync'
worker_connections = 1000
timeout = 30
keepalive = 2

Dentro de Docker (también RHEL, todo lo demás igual), los trabajadores siempre se agotaban y se reiniciaban permanentemente. Tomando las recomendaciones de este hilo, cambié a esto, que funciona perfectamente bien:

workers = 1
threads = 8
worker_class = 'sync'
worker_connections = 1000
timeout = 30
keepalive = 2

Si cree que esto no está relacionado con este hilo, me complace eliminarlo de aquí y ponerlo en otro lugar ;-)

Mejor, Boris

@tilgovi

Este error ocurre en arbiter.py, murder_workers . La función murder_workers se invoca cuando SIG_QUEUE está vacío (por ejemplo, mientras espera señales).

A continuación, comprobaría si se alcanzaba el tiempo de espera cada segundo. El tiempo restante de vida fue siempre de 1 segundo o 0 segundos porque el trabajador gevent está en un bucle infinito controlado mientras self.alive invocó self.notify que actualiza un archivo. Las actualizaciones del archivo son cómo gunicorn está verificando cuándo ocurrió la última vez que estuvo activo.

Por lo tanto, la única forma en que falla la verificación de tiempo de vida en la función murder_workers (por ejemplo, dice que ha estado inactiva demasiado tiempo) es si se cambió la propiedad viva de gevent. Los siguientes métodos controlan esto:

handle_quit
handle_request (si se recibieron el máximo de solicitudes, de forma predeterminada es 2 ^ 64 bits de número de solicitudes o 2 ^ 32 si se trata de un sistema operativo de 32 bits)
changed (invocado desde el cargador si se cambió un archivo)
handle_exit
handle_abort

Estos métodos se invocan a partir de señales.

handle_quit - SIGQUIT, SIGINT
handle_exit - SIGTERM
handle_abort - SIGABRT

Por lo tanto, hay 2 posibles problemas que veo:

  1. El método de notificación no puede actualizar el archivo durante su ciclo
  2. Se envía una señal de forma incorrecta

Creo que la causa más probable es la segunda. La fuente principal de señales se encuentra dentro del archivo de árbitro y se activa con estas excepciones:

  • StopIteration
  • KeyboardInterrupt
  • HaltServer
  • Exception (excepción no controlada)

Creo que la excepción StopIteration es probablemente el culpable activado en el archivo async.py en req = six.next(parser) . Parece que el siguiente método simplemente invoca parser.next ().

Parser.next() genera una excepción StopIteration en las siguientes 2 condiciones:

1. If the message indicates it should close:
    1. http Connection close (and keep-alive false)
    2. WSGI - request method not HEAD, response_length is none, and status code is > 200 (but not 204, or 304)
2. If self.mesg (Request message) is falsey

No estoy seguro de qué podría estar causando eso sin querer, pero de los 62 comentarios con este problema visto en múltiples aplicaciones y entornos, creo que vale la pena investigar más y recomiendo volver a abrirlo o si no nos gusta el título. , crea un nuevo problema global con los trabajadores agotando el tiempo de espera.

Volveré a abrir esto e intentaré probar estas combinaciones:

  • Docker local
  • Docker AWS con Classic Load Balancer
  • Docker AWS con Application Load Balancer

Si alguien quiere crear un repositorio que pueda reproducir esto, sería útil, pero probablemente pueda hacerlo este fin de semana.

Tengo este problema y no uso AWS.
Mi configuración es NGINX -> contenedor Docker (Gunicorn con gevent workers + Django). Estoy usando los tiempos de espera predeterminados del Gunicorn.

¿Algun consejo?

Gracias.

Hola @davidmir ,
Tuve el mismo problema, cambiar el tipo de trabajador no ayudó. Cambiar a un solo trabajador de sincronización con varios subprocesos funcionó para mí:

workers = 1
threads = 8
worker_class = 'sync'
worker_connections = 1000
timeout = 30
keepalive = 2

Mejor, Boris

Si bien se mencionan algunos anteriormente, para aclarar mi propia depuración de este problema, algunos de estos son errores de memoria insuficiente; especialmente si se resuelve cambiando la cuenta regresiva del trabajador a 1.

Esto es especialmente problemático en Docker si tiene algo como esto en su configuración:

workers = multiprocessing.cpu_count() * 2 + 1

Pero están limitando la memoria disponible para el contenedor; el trabajador sincrónico iniciará varios intérpretes de Python potencialmente pesados. Tenga en cuenta que el recuento de CPU se basa en el recuento general de CPU de la máquina, no en lo que ha aprovisionado para que use el contenedor de la ventana acoplable; si está ejecutando un contenedor limitado, debe basar el conteo del trabajador en eso.

Si bien varía de una aplicación a otra, mi regla general es de 256 megas por trabajador en una configuración ajustada y 512 para estar seguro.

Se enfrentó al mismo problema con Classic ELB HTTPS => HTTP Gunicorn Sync Workers

Como otros mencionaron, la solución más fácil fue usar el argumento -k gevent en lugar del trabajador de sincronización predeterminado.

Vimos este mismo problema surgir nuevamente para un contenedor Docker completamente nuevo (alojado en ECS detrás de ALB), y encontramos una solución completamente diferente (pero en retrospectiva, debería haber sido obvio): asignar más memoria al contenedor en CloudFormation plantilla.

Sufrimos de este problema el año pasado y nunca encontramos una causa fundamental, pero esta noche lo vi en un nuevo contenedor y me di cuenta de que el contenedor estaba consumiendo toda la memoria que habíamos asignado. Tan pronto como dupliqué la asignación, los contenedores dejaron de arrojar este error (incluso antes de que asignara más de lo que finalmente consumiría):
https://github.com/hackoregon/civic-devops/issues/157

Enfrentando un problema similar aquí. el código es tan simple como

while true:
      sleep(10)

puede provocar la muerte del trabajador (sin este código, nuestra implementación es normal)
es muy desconcertante, b / c sleep debería enviar un latido.

También ya se han cambiado a gevent, no ayudó. Me pregunto si alguien ha pensado en algo.

salida de muestra:
[2018-06-16 16:00:16 +0000] [136] [CRITICAL] WORKER TIMEOUT (pid:521) [2018-06-16 16:00:16 +0000] [136] [CRITICAL] WORKER TIMEOUT (pid:522) [2018-06-16 16:00:16 +0000] [136] [CRITICAL] WORKER TIMEOUT (pid:523) [2018-06-16 16:00:16 +0000] [136] [CRITICAL] WORKER TIMEOUT (pid:524) [2018-06-16 16:00:16 +0000] [136] [CRITICAL] WORKER TIMEOUT (pid:525) [2018-06-16 16:00:16 +0000] [524] [INFO] Worker exiting (pid: 524) [2018-06-16 16:00:16 +0000] [521] [INFO] Worker exiting (pid: 521) [2018-06-16 16:00:16 +0000] [523] [INFO] Worker exiting (pid: 523) [2018-06-16 16:00:16 +0000] [522] [INFO] Worker exiting (pid: 522) [2018-06-16 16:00:16 +0000] [525] [INFO] Worker exiting (pid: 525) [2018-06-16 16:00:17 +0000] [531] [INFO] Booting worker with pid: 531 /usr/local/lib/python3.6/site-packages/gunicorn/workers/ggevent.py:65: MonkeyPatchWarning: Monkey-patching ssl after ssl has already been imported may lead to errors, including RecursionError on Python 3.6. Please monkey-patch earlier. See https://github.com/gevent/gevent/issues/1016 monkey.patch_all(subprocess=True) [2018-06-16 16:00:17 +0000] [136] [DEBUG] 1 workers [2018-06-16 16:00:17 +0000] [532] [INFO] Booting worker with pid: 532 [2018-06-16 16:00:17 +0000] [533] [INFO] Booting worker with pid: 533 /usr/local/lib/python3.6/site-packages/gunicorn/workers/ggevent.py:65: MonkeyPatchWarning: Monkey-patching ssl after ssl has already been imported may lead to errors, including RecursionError on Python 3.6. Please monkey-patch earlier. See https://github.com/gevent/gevent/issues/1016 monkey.patch_all(subprocess=True) [2018-06-16 16:00:17 +0000] [534] [INFO] Booting worker with pid: 534 /usr/local/lib/python3.6/site-packages/gunicorn/workers/ggevent.py:65: MonkeyPatchWarning: Monkey-patching ssl after ssl has already been imported may lead to errors, including RecursionError on Python 3.6. Please monkey-patch earlier. See https://github.com/gevent/gevent/issues/1016 monkey.patch_all(subprocess=True) [2018-06-16 16:00:17 +0000] [535] [INFO] Booting worker with pid: 535 [2018-06-16 16:00:17 +0000] [136] [DEBUG] 5 workers

Perdón por enturbiar las aguas aquí, pero solo quería compartir mi experiencia, mi pila es HTTP ELB > Nginx > gunicorn/gevent on EC2 , los procesos se ejecutan usando circusd

El problema que encontré fue que después de instrumentar mi aplicación django con elastic-apm, mis comprobaciones de salud HTTP comenzarán a fallar casi de inmediato y gunicorn dejará de responder después de unos segundos.

Probé algunos puntos wrk referencia locales

No noté ningún uso extraño de memoria en valgrind, generalmente alrededor de 4 MB para gunicorn y 40 MB por trabajador

De todos modos, la actualización de gunicorn 19.6.0 > 19.9.0 y gevent 1.2.2 > 1.3.6 me está dando una prueba de salud de ELB sólida de nuevo y ~ 300 rps localmente. Deliberadamente no había estado actualizando gunicorn / gevent hasta que tuve algunos registros de APM en su lugar, parece que hacer eso ha provocado algo de serendipia. La actualización de gevent dio el mayor impulso, comprensiblemente, pero luego la actualización de gunicorn pareció agregar otro 10% más o menos.

Aún no ha mirado los registros de cambios con mucho detalle, ¿quizás los mantenedores pueden arrojar luz sobre la causa más probable?

De todos modos, la actualización de gunicorn 19.6.0> 19.9.0 y gevent 1.2.2> 1.3.6 me está dando un control de estado de ELB de roca sólida nuevamente y ~ 300 rps localmente ... La actualización de gevent dio el mayor impulso

¡Guau, eso es genial!

tema de cierre. sin actividad desde hace un tiempo.

FWIW, todavía tengo este problema @benoitc : - \

Django 2.1.5
gunicorn 19.8.1
gevent 1.2.2
AKS 1.15.7 con 5 nodos (B2 estándar: 2 núcleos virtuales y 2 GB de memoria)
3 contenedores pods / docker, cada uno de los cuales tiene:

    spec:
      containers:
        - name: web-container
          command: ["newrelic-admin"]
          args: [
              "run-program",
              "gunicorn",
              "--limit-request-field_size=16380", # limit also specified in nginx
              "--workers=3", # (2 x vcpu) + 1. vcpu < limit defined in resources
              "-k=gevent",
              "-b=0.0.0.0:8000",
              "ourapp.wsgi",
              "--timeout 60",
              "--log-level=debug",
            ]
          resources:
            requests:
              memory: "200Mi"
              cpu: "250m"
            limits:
              memory: "3000Mi"
              cpu: "2000m"

El mismo problema aquí con EKS, Nginx y un NLB.

@salmicrosoft @sinkr Está bien, pero abra un nuevo problema y proporcione los registros que tenga que puedan ayudarnos a averiguar qué sucedió. Además, ¿qué hace tu aplicación? ¿Tiene alguna solicitud larga?

Tuve el mismo problema en ECS Fargate, pero estaba relacionado con una configuración incorrecta de keepalive / timeout en Docker / gunicorn.conf.py, era
keepalive (no establecido)
tiempo de espera = 2

Antes de arreglarlo funciona bien con un contenedor que se ejecuta localmente, pero fallaba en ECS Fargate, ahora funciona correctamente en ambos entornos.

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