Usando o gunicorn 19.4.5 dentro de uma imagem docker, que está em execução no Ubuntu 14.04 LTS na AWS, vejo tempos limites de trabalho constantes ao executar com> 1 trabalhador de sincronização e o período de tempo limite de 30s padrão. Isso pode estar relacionado a # 588 ou # 942, embora esta seja uma versão significativamente mais recente do gunicorn, então eu não poderia dizer com certeza.
Evidências circunstanciais ao longo de várias execuções parecem sugerir que um dos trabalhadores não foi afetado e são apenas os N-1 restantes que continuam falhando e reiniciando. No entanto, só consegui alguns pontos de dados que sugerem isso, então não tome isso como um sinal forte.
Aqui estão as coisas que verifiquei:
stat -L
em arquivos excluídos, mas evitar que o gunicorn desvincule o arquivo também resulta em stat -L
mostrando que ctime está sendo atualizado normalmente.Eu adicionei algum código a workertmp.py
para registrar o ctime de leitura em cada verificação, e aqui está um desses registros (intercalado entre todos os trabalhadores):
[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)
hrmmm pelo log acima, posso ver que o tempo nunca muda. eu vou verificar
Obrigado, Eu agradeço!
Eu posso ser afetado por este bug.
Estou executando o gunicorn dentro de uma imagem do Docker no AWS (Elastic Beanstalk + EC2 Container Service).
Existem tempos limites de trabalho constantes que começam a acontecer quase imediatamente após a inicialização e apenas ao executar a imagem Docker no AWS.
A mesma solicitação HTTP leva às vezes alguns ms, às vezes 20-30 segundos. Não importa se é para uma página inexistente, uma página de string "Hello world" simples não autenticada ou uma página que busca registros de um banco de dados.
Detalhes adicionais :
Ambientes _não_ afetados :
Logs de contêineres da 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)
(...)
`
Obrigado.
Eu também estou vendo isso. Minha suspeita é o Elastic Load Balancer. Costumávamos usar paste
em uma empresa anterior e isso estava causando problemas com o ELB. Eu acredito que ele reutiliza as conexões de alguma forma e isso estava causando problemas em paste
.
Agora estou em um novo emprego em que usamos gunicorn e estava tudo bem até que começamos a colocar o servidor atrás de um ELB, o webapp agora muitas vezes não responde e aparentemente trava.
Tente usar os trabalhadores gevent
, isso resolveu o problema para mim.
Então, isso é um problema com o ELB mantendo as conexões ativas e prendendo o trabalhador de sincronização? Isso me pareceria muito estranho, já que sinalizamos deliberadamente que a conexão deve ser fechada com o trabalhador de sincronização: https://github.com/benoitc/gunicorn/blob/master/gunicorn/workers/sync.py#L168
Podemos fechar a conexão deliberadamente, no entanto. Se alguém quiser testar mover a chamada client.close()
para ser incondicional, esse pode ser um teste interessante: https://github.com/benoitc/gunicorn/blob/master/gunicorn/workers/sync.py#L199
Você também pode ter certeza de que o tempo limite de inatividade no ELB é menor do que o tempo limite do trabalhador, como uma verificação rápida de sanidade se essa é a causa do problema: http://docs.aws.amazon.com/elasticloadbalancing/latest/ classic / config-idle-timeout.html
@tilgovi a coisa do gevent
. Mas novamente, quem sabe..
isso acontece apenas atrás do ELB e se o protocolo HTTP ou HTTPS estiver definido no ELB.
Se você alterar o protocolo para TCP ou SSL, o problema desaparecerá.
Alguém sabe como consertar ainda usando os trabalhos de sincronização? Usei a correção que descrevi (TCP em vez de HTTP) até agora, quando vou monitorar os logs de acesso e ver o cabeçalho X-Forwarded-For, que está habilitado apenas para HTTP / HTTPS em ELB :)
Estranho, só para ter certeza de que estamos na mesma página, isso significa que existe algum tipo de otimização ao usar a opção HTTP / HTTPS no ELB? E essa otimização está causando problemas com os trabalhos de sincronização?
@ecs Eu acho que no caso do balanceador de carga HTTP / HTTPS, reutilize a mesma conexão TCP, que é mantida pelo ELB ativo por muito tempo - algum tipo disso. Mas isso não explica por que o gevent worker funciona bem ... (embora eu não tenha testado o gevent ainda, apenas leia esses comentários)
A propósito, certamente há muitos fatores (versão do gunicorn, classe de trabalho, dentro do docker ou não, protocolo ELB) que podem influenciar, então seria ótimo se alguém testasse e confirmasse que o protocolo TCP no ELB funciona ao contrário do HTTP. Estou testando no docker hospedado no Ubuntu 14.04 e gunicorn versão 19.3.0
Eu tenho o mesmo problema:
[2016-10-03 12:13:17 +0000] [6] [CRÍTICO] TEMPO LIMITE DO TRABALHADOR (pid: 16)
[2016-10-03 12:13:17 +0000] [16] [INFO] Trabalhador saindo (pid: 16)
[2016-10-03 12:13:17 +0000] [6] [CRÍTICO] TEMPO LIMITE DO TRABALHADOR (pid: 20)
[2016-10-03 12:13:17 +0000] [20] [INFO] Trabalhador saindo (pid: 20)
[2016-10-03 12:13:17 +0000] [33] [INFO] Inicializando trabalhador com pid: 33
Minha configuração.
Estou usando o kube-aws para configurar um cluster kubernetes com core-os no AWS: https://github.com/coreos/coreos-kubernetes/tree/master/multi-node/aws
Eu tenho um aplicativo python usando gunicorn e trabalhos de sincronização. O serviço para eles usa um balanceador de carga HTTPS com o certificado de meus sites. Todos os workers são considerados expirados após o tempo limite padrão de 30s, ao que parece. Eles são todos reiniciados eventualmente. O Kubernetes eventualmente reinicia o contêiner quando ele sai. Essas reinicializações acontecem continuamente. Alguém mencionou acima que o gevent resolve o problema. Eu posso tentar fazer isso, mas eu realmente gostaria de entender por que isso está acontecendo.
Também estamos vendo esse problema. Vou tentar postar mais detalhes quando tiver oportunidade. Ele está relacionado ao trabalhador de sincronização, pois a mudança para o gevent realmente resolve o problema. Isso está na AWS com ECS e ELB.
Tive o mesmo problema estranho com um de nossos aplicativos. Mudar os ouvintes de HTTP para tcp realmente resolve o problema.
Alguém pode me fornecer uma maneira passo a passo de reproduzir o problema? (etapa de configuração e tal) Ou pelo menos me indique uma maneira simples de configurar esse ambiente :) Vou dar uma olhada nele esta semana.
Depender de HTTP para esse balanceador geralmente requer o manuseio do keep-alive behind, (exceto para tcp), portanto, qualquer coisa que use um trabalhador de sincronização pode ser um problema até que o trabalhador de sincronização seja atualizado para seu suporte.
De qualquer forma, me avise.
Basta configurar um aplicativo Flask básico e executá-lo com gunicorn com trabalhos de sincronização dentro do docker no AWS, com balanceamento de carga HTTP e a configuração acima:
Usando o gunicorn 19.4.5 dentro de uma imagem docker, que está em execução no Ubuntu 14.04 LTS na AWS, vejo tempos limites de trabalho constantes ao executar com> 1 trabalhador de sincronização e o período de tempo limite de 30s padrão.
Você não precisa fazer nenhuma solicitação ao aplicativo, apenas monitore os logs e você verá os workers expirando.
Atualmente, estou usando gevent workers com um período de tempo limite de 65s (o tempo limite do AWS ELB é 60s, AFAIK). Ainda encontro erros 504 às vezes, mesmo quando apenas um cliente faz solicitações, com 1 solicitação em andamento por vez, mas ainda não consegui identificar o motivo.
@ obi1kenobi Você tentou aumentar o keepalive para além da opção de tempo limite do ELB?
@lenucksi o keepalive já é maior do que o tempo limite ELB em 5s - espero que os relógios dos servidores não
Eu também encontrei esse problema ao executar o gunicorn 19.6 dentro de um contêiner do Docker em uma instância EC2 atrás de um ELB (usando o protocolo HTTP padrão para proxy reverso para a instância EC2).
Como sugerido anteriormente, definir a classe de trabalho como gevent resolveu esse problema para mim (onde antes eu estava usando a classe de trabalho padrão sync
).
Vou tentar documentar um exemplo mínimo para reproduzir o problema.
Para corroborar o que outros disseram, o ELB parece estar abrindo uma conexão com a instância EC2 e mantendo-a aberta de uma forma que bloqueia o gunicorn de lidar com solicitações adicionais.
Quando essa conexão mantida aberta termina devido ao gunicorn ter atingido o tempo limite da solicitação do ELB, todas as solicitações pendentes enfileiradas atrás dele também falham (incluindo a verificação de integridade do ELB, fazendo com que a instância seja removida do ELB, tornando isso mais difícil de depurar; )).
Este sintoma sugere que esta é uma duplicata do que foi observado na edição anterior que não está relacionada ao Docker: https://github.com/benoitc/gunicorn/issues/588
@jelis Você sabe se isso está relacionado a alguma configuração do kubernetes? O seu problema foi resolvido?
Também estou em um ELB com terminação SSL. Estou vendo isso em meus logs:
[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
Atualização - acabei de mudar de gunicorn para gevent (http://flask.pocoo.org/docs/0.12/deploying/wsgi-standalone/#gevent) e o problema foi resolvido. Isso é uma referência ao meu comentário acima https://github.com/benoitc/gunicorn/issues/1194#issuecomment -283269046
Venho martelando nesse assunto há alguns dias. As notas de todos aqui são fantásticas e estão nos dando uma série de caminhos para buscar soluções / soluções alternativas / atenuações. (o registro do meu trabalho está no bug que estamos rastreando aqui )
Eu apenas tentei usar o gevent com um aumento na contagem de trabalhadores e isso não nos ajudou em nada - na verdade, fez com que parecesse pior - todos os cinco trabalhadores do gevent morreram ao mesmo tempo, o que é um novo comportamento de o que li acima:
[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
Isso é provavelmente alguma bagunça da minha parte, e não era o mesmo comportamento de uma das minhas contrapartes de projeto (com uma base de código semelhante, mas não idêntica em uma implantação AWS / CloudFormation / ALB / ECS quase idêntica). No entanto, decidi relatá-lo caso inspire novos insights sobre as interações entre ALB, ECS, Docker e gunicorn.
Eu tenho uma configuração semelhante (convox executando ELB-> ECS Docker Container-> Gunicorn-> Django) e posso confirmar que as seguintes alterações de configuração parecem ter ajudado:
keepalive = 75 # needs to be longer than the ELB idle timeout
timeout = 90
worker_class = 'gevent'
Eu defino meu tempo limite inativo ELB para 60 segundos.
Antes de alterar essas configurações, eu estava usando os padrões de keepalive, timeout e sync worker.
Curiosamente, esta edição começou a ser exibida às 4h UTC do dia 10 de abril. O aplicativo estava funcionando bem sem nenhuma alteração desde a quinta-feira anterior.
apenas empilhando, sem docker, mas a instância aws nua estava tendo o mesmo problema atrás de um ELB. funciona NP no osx, mas o ubuntu16 com o mesmo problema ELB apareceu. gevent
classe de trabalhador
Alguém neste tópico pode verificar isso?
https://serverfault.com/questions/782022/keepalive-setting-for-gunicorn-behind-elb-without-nginx
@erikcw parece ter encontrado essa solução para funcionar. Eu gostaria de encerrar este problema. Se alguém puder reproduzir isso depois de aumentar o tempo limite do trabalhador Gunicorn e o tempo limite de manutenção de atividade, diga isso.
Como alternativa, diminua o tempo limite de inatividade para ELB.
Um cliente em estado selvagem (ou um cliente nefasto) não poderia agir como o ELB e causar o mesmo problema?
@ six8 sim. ELB também não o protege disso. A documentação discute isso: http://docs.gunicorn.org/en/latest/design.html#choosing -a-worker-type
Algumas pessoas não se importam com essa ameaça e querem apenas implantar o Gunicorn, na borda ou atrás de um ELB. O problema discutido aqui são os tempos limite do trabalhador causados pelo próprio ELB. Eu gostaria de fornecer a configuração recomendada que faz o gunicorn funcionar por trás do ELB com trabalhos de sincronização e sem um proxy reverso adicional.
Eu tentei a solução de @erikcw também alterando a invocação do gunicorn para:
CMD [ "gunicorn", "-k", "gevent", "--timeout", "10", "--keep-alive", "75", "--paste", "/etc/jzoo/app.ini" ]
Infelizmente, isso não ajuda:
[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)
Tenho um aplicativo em execução no ECS por trás de um ALB com trabalhos de sincronização Gunicorn. Eu não vi nenhum problema ainda.
Qualquer pessoa pode fornecer uma implantação reproduzível?
empilhando, também. vendo este problema usando Kubernetes na AWS com ELB. Atualmente temos 8 trabalhadores em execução. Por https://serverfault.com/questions/782022/keepalive-setting-for-gunicorn-behind-elb-without-nginx/ , vamos aumentar keepalive
e, de acordo com este tópico, vamos tentar para usar gevent
workers em seu lugar. Mas agora, o que está falhando são alguns testes de desempenho para chamadas de API que não deveriam estar bloqueando / causando tempo limite por conta própria. gostaria de saber o que está acontecendo aqui com sync
trabalhadores. Mesmo se conseguirmos fazer isso funcionar de acordo com algumas das boas diretrizes neste tópico, gostaríamos de ter um pouco mais de confiança sobre o que está acontecendo antes de implantar para produção.
Definir a classe --worker para --worker-class gevent
funcionou para mim. Obrigado pelos comentários e ajuda!
@wichert, isso é muito estranho. Com o trabalhador gevent, os trabalhadores devem notificar o árbitro de sua vida em um greenlet separado de quaisquer conexões. Sua configuração de keep-alive não deve afetar isso de forma alguma. Algo está errado com seu aplicativo, de forma que o gevent não está funcionando conforme projetado, ou algo na configuração é problemático que pode ser comum a esses outros cenários.
Por favor, todos neste tópico, forneçam um aplicativo que reproduza este problema. Eu não fui capaz de reproduzi-lo. Sem etapas para reproduzir, estou tentado a encerrar. Há uma mistura de recomendações e talvez questões muito diferentes enterradas nesses comentários. É difícil saber o que fazer com esse problema.
@tilgovi Eu tive esse problema ao não especificar a classe de trabalho a ser gevent (por exemplo, usando o trabalhador de sincronização padrão). Minha configuração é virtualenv usando pypy3 (PyPy 5.8.0-beta0), falcon 1.2, etc (entendendo que Falcon não é oficialmente compatível com pypy3). Eu usei o cookiecutter de https://github.com/7ideas/cookiecutter-falcon e atualizei para todos os pacotes mais recentes e ao tentar carregar o sample_resource no navegador e acertá-lo várias vezes com httpie veria intermitentemente o erro de falha do trabalhador ( por exemplo, a solicitação seria atrasada e eu veria o erro; se eu não cancelasse a solicitação, ele acabaria respondendo). Isso só aconteceu com a classe de trabalho de sincronização padrão. Quando eu especifiquei para usar gevent, tudo funcionou.
Obrigado, @ jhillhouse92 , vou tentar.
Continuo a ver problemas com tempos limite, @tilgovi. Estarei solucionando mais isso amanhã e postarei uma atualização com informações mais precisas. Por favor, mantenha este problema aberto; você está certo de que pode haver uma variedade de problemas acontecendo, mas o tema geral é que os trabalhadores gunicorn (talvez apenas com a classe de trabalho de sincronização, tbd) estão tendo problemas de tempo limite ao usar o gunicorn com um aplicativo implantado usando AWS / ELB. Há algo errado aqui, mesmo que não tenhamos isolado o problema exato. Vale a pena pesquisar mais. Vou atualizar amanhã.
Vale a pena notar que tive esse problema localmente, não dentro do Docker / AWS / ELB com a pilha acima que mencionei.
Portanto, estou usando gevent, tentando capturar meus logs de acesso e tentando implantar meu aplicativo usando AWS / ELB.
Comandos 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"]
Estou recebendo erros loucos de OOM em relação ao código de erro 14, independentemente de como eu defini os limites. Alguém mais viu isso no contexto deste problema? Anteriormente, eu conseguia ver os tempos limite do trabalhador. Com minhas configurações atuais, não consigo reproduzir os tempos limite / chegar tão longe.
[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, não vejo isso localmente sem o docker. Não vejo isso localmente com o Docker. Isso, e os problemas de tempo limite, só aparecem aparentemente na pilha Docker / AWS / ELB (para mim).
@tilgovi Uma coisa que eu fiz de errado inicialmente (como pode ser visto no trecho que postei acima) é que o tempo limite foi definido incorretamente para 10 segundos. Depois de mudar isso para 75 segundos, o número de tempos limite do trabalhador caiu significativamente para talvez alguns por dia. Para completar, este é o comando exato que estou usando para iniciar nosso aplicativo:
gunicorn -k gevent --timeout 90 --keep-alive 75 --paste /etc/jzoo/app.ini "$@"
O arquivo .ini tem a seguinte aparência:
[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
A quantidade de tráfego não parece ser um fator - vejo isso acontecendo em nosso ambiente de controle de qualidade, que vê muito pouco tráfego.
Observando a frequência com que isso acontece, fico me perguntando se isso pode estar relacionado a reinicializações de aplicativos.
Eu tenho um problema semelhante. Depois de algumas investigações, acho que provavelmente é um erro de conexão de rede, não do gunicorn.
Esta é minha configuração:
Curiosamente, a maioria das solicitações do servidor de aplicativos para o servidor postgres estava OK, exceto uma. Essa consulta parece ser executada para sempre, o que expira o trabalho do gunicorn.
O problema desaparece se eu usar o aplicativo localmente.
O problema também desaparece se eu não encaixar o servidor de aplicativos.
Minha correção temporal é abrir todas as conexões entre o servidor de aplicativos e o servidor postgres por meio da configuração do grupo de segurança da AWS. Agora tudo funciona corretamente novamente.
Meu palpite é que há um problema de conexão entre o contêiner Python e a AWS. Vou atualizar depois de examinar o fluxo de log da AWS completamente.
Obrigado!! Alterar o protocolo ELB e de instância de HTTP para TCP funcionou bem 👍
O problema não parece específico da AWS, mas do próprio Docker quando combinado com o Gunicorn. Também vejo isso com gevent
, pelo menos em nosso ambiente de produção.
@tilgovi Este é um aplicativo simples para recriar esse erro (de vez em quando, não encontrei o padrão, talvez você possa):
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 executar: docker build -t gunicorn-and-docker . && docker run -p 8000:8000 -it --rm gunicorn-and-docker
Os registros ficarão assim (pelo menos para mim no 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
Oi,
Recentemente, encontrei o mesmo problema.
No meu caso (ECS + gunicorn 19.7.1 + Django 1.11.5) eu (aparentemente) consegui resolver simplesmente aumentando a quantidade de memória dedicada ao container na definição da tarefa (de 128 para 256mb).
Sem mais erros até agora. Vou relatar aqui se isso acontecer novamente.
Adicionando um pouco ao refrão aqui, mas eu fui capaz de resolver isso apenas mudando para gevent.
Tentei aumentar o tempo limite para 90 e o keepalive para 75 com o trabalhador de sincronização sem sorte.
Além disso, curiosamente, meu ELB neste cenário está apenas fazendo encaminhamento de nível TCP e não HTTP.
Ok, encontrei algumas referências que explicam isso. [1]
Isso poderia ser resolvido com pequenas mudanças no lado do Gunicorn. Se, no trabalhador de sincronização, após aceitar uma nova conexão, chamarmos select()
com um tempo limite curto, então poderemos lidar com essas conexões. Pode ser um pouco complicado, especialmente com vários soquetes de escuta. A coisa mais simples seria ter um tempo limite para o primeiro byte. Também não tenho certeza de como isso interagiria com SSL.
[1] https://cloudavail.com/2013/12/21/aws-elb-pre-open-connection-expose-part-1/
Se você está passando por isso e não deseja usar gevent / eventlet / asyncio, recomendo mudar para o trabalhador encadeado (forneça a configuração --threads
).
@tilgovi O problema parece existir também com o gevent worker, se você olhar meu exemplo acima.
@jmagnusson seu exemplo (a partir deste comentário: https://github.com/benoitc/gunicorn/issues/1194#issuecomment-331740187) parece estar usando o trabalhador de sincronização.
[2017-09-23 22:31:00 +0000] [1] [INFO] Usando trabalhador: sincronizar
@tilgovi Verdadeiro, mas também experimentei isso com o trabalhador gevent
, em produção. Tentarei encontrar algum tempo para reproduzir com gevent.
Posso ser apenas eu (bobo), mas no grupo de segurança EC2 -> regras de entrada, tenho uma regra TCP personalizada para a porta 5000 (gunicorn aqui) para permitir apenas um único IP (meu IP: XX.XX.XX.XX / 32), mudar isso para todos os IPs ajudará.
Eu também encontro o 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.
Eu adicionei o log de depuração worker pid {WORKER_PID} notify
.
De acordo com o log de depuração,
SIGTERM
. Quando o tempo limite normal chegasse, o mestre o mataria em SIGKILL
coercitivamente.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: quando eu uso eventlet
como trabalhador, está tudo bem.
Vou encerrar este problema porque acho que está meio desatualizado. Pelo que posso determinar, o comportamento observado é devido ao AWS Classic Load Balancers fazer uma otimização pré-aberta. Essa otimização só é feita por Classic Load Balancers, de acordo com a documentação de funcionamento do load balancing . Mudar para balanceadores de carga de aplicativos deve resolver o problema. Além disso, conforme documentado nesta postagem do blog , é possível solicitar que a AWS desative a otimização pré-aberta ou aumente o tempo limite do trabalhador para Gunicorn.
@tilgovi FWIW Eu vi isso com ALB. Nunca usei balanceadores de carga clássicos.
@tilgovi Eu também observei isso repetidamente em ambientes somente ALB, nunca tendo usado o clássico. Mesmo com ajustes de tempo limite do trabalhador, continuamos a ver isso.
@tilgovi eu me encontrei com isso. Nunca usei AWS.
Alguém tem que ajudar a reproduzir isso, então, e tentar depurá-lo. Não consigo reproduzi-lo com ALB e não consigo ver como reproduzi-lo fora do AWS.
@xgfone você pode querer abrir seu próprio problema, o título deste problema é "docker + AWS"
Alguém experimentou isso com os balanceadores de carga da AWS, mas sem o Docker? Estou um pouco confuso, tenho que admitir :)
Minha impressão era que o problema estava realmente mais relacionado ao Docker - pelo menos eu tive exatamente os mesmos problemas ao executar vários trabalhos de sincronização do gunicorn dentro do Docker em minha máquina local.
Esta configuração funcionou bem sem Docker em máquinas Ubuntu e RHEL, ambos bare metal e virtualizados no Digital Ocean:
workers = 2
worker_class = 'sync'
worker_connections = 1000
timeout = 30
keepalive = 2
Dentro do Docker (também RHEL, todo o resto igual), os workers sempre atingiam o tempo limite e continuavam reiniciando permanentemente. Pegando as recomendações deste tópico, mudei para este, que funciona perfeitamente bem:
workers = 1
threads = 8
worker_class = 'sync'
worker_connections = 1000
timeout = 30
keepalive = 2
Se você acha que isso não está relacionado a este tópico, estou feliz em removê-lo daqui e colocá-lo em outro lugar ;-)
Atenciosamente, Boris
@tilgovi
Este erro ocorre no arbiter.py, murder_workers
. A função murder_workers
é chamada quando SIG_QUEUE
está vazio (por exemplo, enquanto espera por sinais).
Em seguida, ele verificaria se o tempo limite foi atingido a cada segundo. O tempo restante de vida foi sempre 1 ou 0 segundos porque o trabalhador gevent está em um loop infinito controlado enquanto self.alive
invocou self.notify
que atualiza um arquivo. As atualizações para o arquivo são como o gunicorn está verificando quando ocorreu o último horário ativo.
Assim, a única maneira de a verificação do tempo de vida na função murder_workers
falhar (por exemplo, dizer que está ociosa por muito tempo) é se a propriedade gevent alive foi alterada. Os métodos a seguir controlam isso:
handle_quit
handle_request
(se as solicitações máximas foram recebidas, por padrão é 2 ^ 64 bits do número de solicitações ou 2 ^ 32 se o sistema operacional de 32 bits)
changed
(invocado do reloader se um arquivo foi alterado)
handle_exit
handle_abort
Esses métodos são invocados a partir de sinais
handle_quit
- SIGQUIT, SIGINT
handle_exit
- SIGTERM
handle_abort
- SIGABRT
Portanto, existem 2 problemas possíveis que vejo:
Acho que a causa mais provável é a 2ª. A principal fonte de sinais está dentro do arquivo do árbitro e acionada por estas exceções:
StopIteration
KeyboardInterrupt
HaltServer
Exception
(exceção não tratada)Acho que a exceção StopIteration é provavelmente o culpado disparado no arquivo async.py em req = six.next(parser)
. Parece que o próximo método está apenas invocando parser.next ().
Parser.next()
levanta uma exceção StopIteration
nas 2 condições a seguir:
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
Não tenho certeza do que exatamente pode estar causando isso de forma não intencional, mas de 62 comentários com este problema sendo visto em vários aplicativos e ambientes, acho que vale a pena investigar mais e recomendo reabri-lo ou se não gostamos do título , criar um novo problema global com os trabalhadores atingindo o limite de tempo crítico.
Vou reabrir e tentar testar essas combinações:
Se alguém quiser criar um repo que possa reproduzir isso, seria útil, mas provavelmente poderei fazê-lo neste fim de semana.
Estou tendo esse problema e não estou usando o AWS.
Minha configuração é NGINX -> contêiner Docker (Gunicorn com gevent workers + Django). Estou usando os tempos limite padrão do Gunicorn.
Alguma dica?
Obrigado.
Olá @davidmir ,
Tive o mesmo problema, mudar o tipo de trabalhador não adiantou. Mudar para um único trabalhador de sincronização com vários threads funcionou para mim:
workers = 1
threads = 8
worker_class = 'sync'
worker_connections = 1000
timeout = 30
keepalive = 2
Atenciosamente, Boris
Embora sejam mencionados alguns acima, para esclarecer minha própria depuração desse problema, alguns deles são erros de falta de memória; especialmente se for resolvido alterando a contagem regressiva do trabalhador para 1.
Isso é especialmente problemático no Docker se você tiver algo assim em sua configuração:
workers = multiprocessing.cpu_count() * 2 + 1
Mas estão limitando a memória disponível para o contêiner; o trabalhador síncrono iniciará vários interpretadores python potencialmente pesados. Observe que a contagem da CPU é baseada na contagem geral da CPU da máquina, não no que você provisionou o contêiner do docker para usar; se você estiver executando um contêiner limitado, deve basear a contagem do trabalhador nisso.
Embora varie de aplicativo para aplicativo, minha regra prática é 256 megas por trabalhador em uma configuração enxuta e 512 para ser seguro.
Enfrentou o mesmo problema usando Classic ELB HTTPS => HTTP Gunicorn Sync Workers
Como outros mencionaram, a correção mais fácil era usar o argumento -k gevent
vez do trabalhador de sincronização padrão.
Vimos esse mesmo problema surgir novamente para um contêiner Docker totalmente novo (hospedado em ECS atrás do ALB) e encontramos uma solução totalmente diferente (mas em retrospectiva, deveria ter sido óbvia): alocar mais memória para o contêiner em CloudFormation modelo.
Sofremos com esse problema no ano passado e nunca encontramos a causa raiz de uma arma fumegante, mas hoje à noite eu descobri em um novo contêiner e por acaso percebi que o contêiner estava consumindo toda a memória que havíamos alocado. Assim que dobrei a alocação, os contêineres pararam de lançar este erro (mesmo antes de eu alocar mais do que acabaria por consumir):
https://github.com/hackoregon/civic-devops/issues/157
Enfrentando um problema semelhante aqui. o código é tão simples quanto
while true:
sleep(10)
pode levar o trabalhador à morte (sem este código, nossa implantação é normal)
é muito intrigante, b / c sleep
deve enviar um batimento cardíaco.
também já mudou para gevent, não ajudou. Será que alguém tem algum pensamento?
saída de amostra:
[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
Desculpe por turvar as águas aqui, mas só queria compartilhar minha experiência, minha pilha é HTTP ELB > Nginx > gunicorn/gevent on EC2
, processos executados usando circusd
O problema que descobri foi que, após instrumentar meu aplicativo django com elastic-apm, minhas verificações de integridade de HTTP começarão a falhar quase imediatamente e o gunicorn deixaria de responder após alguns segundos.
Eu tentei alguns benchmarks locais de wrk
contra minha verificação de saúde, a sincronização estava obtendo cerca de 300rps para 1-5 workers, mas o gevent recebia 1rps. Desligar o apm aumentou o gevent até cerca de 50 rps e um aumento desprezível para a sincronização.
Não notei nenhum uso estranho de memória no valgrind, normalmente cerca de 4 MB para gunicorn e 40 MB por trabalhador
De qualquer forma, atualizar gunicorn 19.6.0 > 19.9.0
e gevent 1.2.2 > 1.3.6
está me dando uma excelente verificação de integridade do ELB novamente e ~ 300rps localmente. Deliberadamente, não estive atualizando o gunicorn / gevent até que algum registro do APM estivesse em vigor, parece que fazer isso gerou algum acaso. A atualização do gevent deu o maior impulso, compreensivelmente, mas a atualização do gunicorn pareceu adicionar outros 10% ou mais.
Ainda não olhou para os changelogs com muitos detalhes, talvez os mantenedores possam lançar luz sobre a causa mais provável?
De qualquer forma, atualizar gunicorn 19.6.0> 19.9.0 e gevent 1.2.2> 1.3.6 está me dando uma excelente verificação de integridade de ELB novamente e ~ 300rps localmente ... Atualizar gevent deu o maior impulso
Uau, isso é muito legal!
edição de encerramento. nenhuma atividade desde há algum tempo.
FWIW, ainda estou tendo esse problema @benoitc : - \
Django 2.1.5
gunicorn 19.8.1
gevent 1.2.2
AKS 1.15.7 com 5 nós (padrão B2's - 2 vcores e 2 GB de memória)
3 pods / contêineres docker, cada um dos quais com:
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"
O mesmo problema aqui com EKS, Nginx e um NLB.
@salmicrosoft @sinkr OK, mas abra um novo problema e forneça todos os logs que você possui que podem nos ajudar a descobrir o que aconteceu. Além disso, o que seu aplicativo faz? Você tem algum pedido longo?
Tive o mesmo problema no ECS Fargate, mas estava relacionado a configurações incorretas de keepalive / timeout em Docker / gunicorn.conf.py, era
keepalive (não definido)
tempo limite = 2
Antes de consertar, funciona bem com um contêiner rodando localmente, mas falhou no ECS Fargate, agora funciona corretamente em ambos os ambientes.
Comentários muito úteis
Tente usar os trabalhadores
gevent
, isso resolveu o problema para mim.