Gunicorn: Тайм-аут работников синхронизации Gunicorn на Docker + AWS

Созданный на 29 янв. 2016  ·  78Комментарии  ·  Источник: benoitc/gunicorn

Используя gunicorn 19.4.5 внутри образа докера, который работает в Ubuntu 14.04 LTS на AWS, я вижу постоянные тайм-ауты рабочих при работе с> 1 синхронизирующим рабочим и периодом ожидания по умолчанию 30 секунд. Это может быть связано с # 588 или # 942, хотя это значительно более новая версия Gunicorn, поэтому я не могу сказать наверняка.

Косвенные свидетельства нескольких прогонов, кажется, предполагают, что один из рабочих не пострадал, и только оставшиеся рабочие N-1 продолжают выходить из строя и перезагружаться. Однако мне удалось получить лишь несколько данных, которые предполагают это, так что не воспринимайте это как сильный сигнал.

Вот что я проверил:

  • Возникают ли проблемы вне докера или при использовании того же образа докера, но не в AWS?
    Нет, мне удалось воспроизвести проблему только с докером на AWS.
  • Инициализация приложения занимает более 30 секунд?
    Нет, приложение завершает инициализацию менее чем за 1 секунду.
  • Получает ли приложение запрос, который приводит к зависанию?
    Проблема возникла без каких-либо запросов к приложению.
  • Есть ли в приложении неработающий код инициализации, который сбивает с толку пулеметчика?
    Проблема возникала при запуске Gunicorn в той же конфигурации (с> 1 исполнителем синхронизации), но с другим приложением. Это новое приложение без проблем запускается на Gunicorn при использовании рабочих gevent.
  • Файловая система докера не может обновить ctime?
    См. Журнал ниже - ctime обычно работает нормально. Файловая система Docker не позволяет использовать stat -L для удаленных файлов, но предотвращение отключения файла от Gunicorn также приводит к тому, что stat -L показывает, что ctime обновляется как обычно.

Я добавил код в workertmp.py чтобы регистрировать время чтения при каждой проверке, и вот один такой журнал (чередующийся между всеми рабочими):

[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 -

Самый полезный комментарий

Попробуйте вместо этого использовать gevent worker, это решило проблему для меня.

Все 78 Комментарий

хмммм из журнала выше я вижу, что время никогда не меняется. я проверю

Спасибо, я ценю это!

Эта ошибка может затронуть меня.

Я запускаю gunicorn внутри образа Docker на AWS (Elastic Beanstalk + EC2 Container Service).
Существуют постоянные тайм-ауты рабочих, которые начинаются почти сразу после инициализации и только при запуске образа Docker на AWS.
Один и тот же HTTP-запрос иногда занимает несколько мс, а иногда 20-30 секунд. Не имеет значения, если это несуществующая страница, простая неаутентифицированная страница со строкой «Hello world» или страница, которая извлекает записи из базы данных.

Дополнительные сведения :

  • Версии Gunicorn : 19.5.0 и 19.6.0.
  • Базовый образ Docker : python: 3.4 ( ОС : Debian Jessie)
  • Версия Docker : 1.9.1 (под управлением Amazon ECS), ОС : Amazon Linux AMI 2016.03 (под управлением Amazon EB).
  • Фреймворк веб-приложений : Django версий 1.9.6 и 1.9.7.

Среды _не_ затронуты :

  • Локальный компьютер , как внутри, так и снаружи контейнера Docker. ОС : Ubuntu 16.04 LTS, Docker : 1.11.2.
  • Heroku ( ОС : Ubuntu 14.04 LTS)

Журналы контейнеров 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)
(...)

`

Спасибо.

Я тоже это вижу. Подозреваю, что это Elastic Load Balancer. Раньше мы использовали paste в предыдущей компании, и это вызывало проблемы с ELB. Я считаю, что он каким-то образом повторно использует соединения, и это вызывало заминки в paste .

Сейчас я нахожусь на новой работе, где мы используем Gunicorn, и все было хорошо, пока мы не начали размещать сервер за ELB, веб-приложение теперь часто очень не отвечает и, похоже, зависает.

Попробуйте вместо этого использовать gevent worker, это решило проблему для меня.

Так это проблема с ELB, который поддерживает соединения и связывает синхронизатора? Это может показаться мне очень странным, поскольку мы намеренно сигнализируем, что соединение должно быть закрыто с помощью синхронизатора: https://github.com/benoitc/gunicorn/blob/master/gunicorn/workers/sync.py#L168

Но мы могли бы намеренно закрыть соединение. Если кто-то хочет проверить безусловность перемещения вызова client.close() это может быть интересным тестом: https://github.com/benoitc/gunicorn/blob/master/gunicorn/workers/sync.py#L199

Вы также можете убедиться, что тайм-аут простоя на ELB меньше, чем тайм-аут рабочего, в качестве быстрой проверки работоспособности, что это даже причина проблемы: http://docs.aws.amazon.com/elasticloadbalancing/latest/ классический / config-idle-timeout.html

@tilgovi - это мое лучшее предположение, потому что а) это происходит, только если пулемет находится за ELB, и б) проблема устраняется с помощью рабочего gevent . Но опять же, кто знает ...

это происходит только за ELB, и если протокол HTTP или HTTPS установлен на ELB.
Если вы измените протокол на TCP или SSL, проблема исчезнет.
Кто-нибудь знает, как это исправить до сих пор с помощью синхронизаторов? Я использовал описанное мной исправление (TCP вместо HTTP) до сих пор, когда собираюсь отслеживать журналы доступа и видеть заголовок X-Forwarded-For, который включен только для HTTP / HTTPS на ELB :)

Странно, просто чтобы убедиться, что мы находимся на одной странице, это означает, что есть какая-то оптимизация при использовании параметра HTTP / HTTPS в ELB? И эта оптимизация вызывает проблемы с синхронизаторами?

@ecs Я думаю, что в случае балансировщика нагрузки HTTP / HTTPS повторно используйте одно и то же TCP-соединение, которое ELB поддерживает долгое время - что-то в этом роде. Но это не объясняет, почему gevent worker работает нормально ... (хотя я еще не тестировал gevent, просто прочтите эти комментарии)

Кстати, существует множество факторов (версия пулемета, рабочий класс, внутренний докер или нет, протокол ELB), которые могут влиять, поэтому было бы здорово, если бы кто-то протестировал и подтвердил, что протокол TCP на ELB работает в отличие от HTTP. Я тестирую докер на Ubuntu 14.04 и gunicorn версии 19.3.0.

У меня точно такая же проблема:
[2016-10-03 12:13:17 +0000] [6] [КРИТИЧНО] ТАЙМ-АУТ РАБОТНИКА (pid: 16)
[2016-10-03 12:13:17 +0000] [16] [INFO] Сотрудник завершает работу (pid: 16)
[2016-10-03 12:13:17 +0000] [6] [КРИТИЧЕСКИЙ] ТАЙМ-АУТ РАБОТНИКА (pid: 20)
[2016-10-03 12:13:17 +0000] [20] [INFO] Сотрудник завершает работу (pid: 20)
[2016-10-03 12:13:17 +0000] [33] [INFO] Загрузка worker с pid: 33

Моя установка.

Я использую kube-aws для настройки кластера kubernetes с core-os на AWS: https://github.com/coreos/coreos-kubernetes/tree/master/multi-node/aws

У меня есть приложение на Python, использующее воркеров-пулеметчиков и синхронизаторов. Сервис для них использует балансировщик нагрузки HTTPS с сертификатом моих сайтов. Все рабочие процессы считаются истекшими после тайм-аута по умолчанию, равного 30 секундам. В конечном итоге все они перезапускаются. Kubernetes в конечном итоге перезапускает контейнер при выходе ... эти перезапуски происходят постоянно. Кто-то выше упомянул, что gevent решает проблему, я могу попробовать это, но мне действительно хотелось бы понять, почему это происходит.

В настоящее время мы тоже сталкиваемся с этой проблемой, я постараюсь опубликовать более подробную информацию, когда у меня будет возможность. Это связано с исполнителем синхронизации, поскольку переход на gevent действительно решает проблему. Это на AWS с ECS и ELB.

Была такая же странная проблема с одним из наших приложений. Смена слушателей с HTTP на TCP действительно решает проблему.

кто-нибудь может предоставить мне пошаговый способ воспроизвести проблему? (этап настройки и тому подобное) Или, по крайней мере, укажите мне простой способ настройки этой среды :) Я посмотрю на это на этой неделе.

Использование HTTP для такого балансировщика обычно требует обработки keep-alive (кроме tcp), поэтому все, что использует синхронизирующий воркер, может быть проблемой до тех пор, пока синхронизирующий воркер не будет обновлен для его поддержки.

В любом случае дайте мне знать.

Просто настройте базовое приложение Flask и запустите его с помощью gunicorn с рабочими процессами синхронизации внутри докера на AWS, с балансировкой нагрузки HTTP и настройкой сверху:

Используя gunicorn 19.4.5 внутри образа докера, который работает в Ubuntu 14.04 LTS на AWS, я вижу постоянные тайм-ауты рабочих при работе с> 1 синхронизирующим рабочим и периодом ожидания по умолчанию 30 секунд.

Вам не нужно делать какие-либо запросы к приложению, просто следите за журналами, и вы увидите, что рабочие вышли из строя.

  • Я могу подтвердить это поведение, а также базовый подход к его воспроизведению.

    • Поведение не ограничивается Docker, а скорее настройкой синхронизатора / keepalive, поэтому вы можете подумать об изменении заголовка ...

  • Я изменил настройку keepalive, чтобы следовать тому, что описано здесь: https://serverfault.com/questions/782022/keepalive-setting-for-gunicorn-behind-elb-without-nginx/ (самая интересная часть - это цитата из документации AWS ELB) и обнаружил, что сервер больше не демонстрирует такое поведение.
  • Кроме того, я дополнительно перешел на рабочий класс gthread и обнаружил, что до сих пор результат был очень приемлемым.

В настоящее время я использую gevent worker с периодом ожидания 65 секунд (таймаут AWS ELB составляет 60 секунд, AFAIK). Я все еще иногда сталкиваюсь с ошибкой 504, даже когда только один клиент делает запросы, с одним запросом в полете за раз, но я пока не смог определить причину.

@ obi1kenobi Вы пытались увеличить время активности до значения, превышающего время ожидания ELB?

@lenucksi время

Я тоже столкнулся с этой проблемой при запуске gunicorn 19.6 внутри контейнера Docker на экземпляре EC2 за ELB (с использованием протокола HTTP по умолчанию для обратного проксирования экземпляра EC2).

Как предлагалось ранее, установка рабочего класса на gevent решила эту проблему для меня (где раньше я использовал рабочий класс по умолчанию sync ).

Я постараюсь задокументировать минимальный пример для воспроизведения проблемы.

Чтобы подтвердить то, что говорили другие, ELB, похоже, открывает соединение с экземпляром EC2 и удерживает его открытым таким образом, что блокирует Gunicorn от обработки дополнительных запросов.

Когда это удерживаемое открытое соединение завершается из-за тайм-аута тайм-аута запроса от ELB, все ожидающие запросы, поставленные в очередь за ним, также терпят неудачу (включая проверку работоспособности ELB, в результате чего экземпляр удаляется из ELB, что затрудняет отладку; )).

Этот симптом предполагает, что это дубликат того, что наблюдалось в предыдущей проблеме, не связанной с Docker: https://github.com/benoitc/gunicorn/issues/588

@jelis Вы знаете, связано ли это с какой-то конфигурацией кубернетов? Была ли решена ваша проблема?

Я также нахожусь на ELB с завершением SSL. Я вижу это в своих журналах:

[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

Обновление - я только что переключился с gunicorn на gevent (http://flask.pocoo.org/docs/0.12/deploying/wsgi-standalone/#gevent), и проблема решена. Это ссылка на мой комментарий выше https://github.com/benoitc/gunicorn/issues/1194#issuecomment -283269046

Я уже пару дней забиваюсь по этому поводу. Все заметки здесь фантастические, и они дают нам ряд возможностей для поиска исправлений / обходных путей / смягчения последствий. (журнал моей работы в жука мы отслеживания здесь )

Я только что попытался использовать gevent с увеличением количества рабочих, и это нам совсем не помогло - на самом деле это удивительно ухудшило вид - все пять рабочих gevent умерли одновременно, что является новым поведением от что я прочитал выше:

[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

Скорее всего, это какая-то ошибка с моей стороны, и это не было таким же поведением, как у одного из моих коллег по проекту (с похожей, но не идентичной кодовой базой в почти идентичном развертывании AWS / CloudFormation / ALB / ECS). Однако я решил, что сообщу об этом, если это вдохновит на какие-либо новые взгляды на взаимодействие между ALB, ECS, Docker и gunicorn.

У меня аналогичная установка (конвокс с запущенным ELB-> ECS Docker Container-> Gunicorn-> Django), и я могу подтвердить, что следующие изменения конфигурации, похоже, помогли:

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

Я установил тайм-аут простоя ELB на 60 секунд.

Перед изменением этих настроек я использовал значения по умолчанию для keepalive, timeout и sync worker.

Интересно, что эта проблема начала проявляться в 4 утра по всемирному координированному времени 10 апреля. Приложение работало нормально без каких-либо изменений с предыдущего четверга.

просто накапливается, докера нет, но у экземпляра aws была такая же проблема за ELB. работает NP на osx, но возникла ubuntu16 с такой же проблемой ELB. gevent worker class, кажется, исправляет это [для меня].

Может ли кто-нибудь в этой ветке проверить это?
https://serverfault.com/questions/782022/keepalive-setting-for-gunicorn-behind-elb-without-nginx

@erikcw, похоже, нашел, что это решение работает. Я бы хотел закрыть этот вопрос. Если кто-то может воспроизвести это после увеличения тайм-аута рабочего стола Gunicorn и тайм-аута поддержки активности, сообщите об этом.

В качестве альтернативы уменьшите тайм-аут простоя для ELB.

Не мог ли клиент в дикой природе (или гнусный клиент) действовать как ELB и вызывать ту же проблему?

@ six8 да. ELB также не защищает вас от этого. В документации обсуждается это: http://docs.gunicorn.org/en/latest/design.html#choosing -a-worker-type

Некоторых людей не волнует эта угроза, и они просто хотят развернуть Gunicorn на границе или за ELB. Здесь обсуждается проблема таймаутов рабочих, вызванная самим ELB. Я хотел бы предоставить рекомендуемую конфигурацию, которая заставляет Gunicorn работать за ELB с рабочими процессами синхронизации и без дополнительного обратного прокси.

Я также попробовал решение @erikcw , изменив вызов пушки на:

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

К сожалению, это не помогает:

[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)

У меня есть приложение, работающее на ECS за ALB с синхронизаторами Gunicorn. Я пока не видел никаких проблем.

Может ли кто-нибудь обеспечить воспроизводимое развертывание?

нагромождение, а также. видя эту проблему при использовании Kubernetes на AWS с ELB. В настоящее время работает 8 рабочих. Согласно https://serverfault.com/questions/782022/keepalive-setting-for-gunicorn-behind-elb-without-nginx/ , мы собираемся увеличить keepalive , и в этом потоке мы попытаемся вместо этого использовать gevent worker. Но прямо сейчас не работают некоторые тесты производительности для вызовов api, которые сами по себе не должны блокировать / вызывать тайм-ауты. хотел бы знать, что здесь происходит с рабочими sync . даже если мы добьемся того, чтобы это работало в соответствии с некоторыми хорошими рекомендациями в этом потоке, мы хотели бы немного больше уверенности в том, что происходит, перед развертыванием в производственной среде.

Установка --worker-class на --worker-class gevent сработала для меня. Спасибо за комментарии и помощь!

@wichert, это очень странно. С помощью gevent worker рабочие должны уведомлять арбитра о своей жизнеспособности в отдельном окне от любых подключений. Ваш параметр keep-alive вообще не должен влиять на это. Что-то не так с вашим приложением, например, gevent не работает так, как задумано, или что-то в настройке проблематично, что может быть общим для этих других сценариев.

Пожалуйста, всем участникам этой ветки предоставьте приложение, которое воспроизводит эту проблему. Мне не удалось воспроизвести это. Без шагов по воспроизведению я испытываю искушение закрыть. В этих комментариях скрыто множество рекомендаций и, возможно, очень разные проблемы. Трудно понять, что делать с этой проблемой.

@tilgovi У меня https://github.com/7ideas/cookiecutter-falcon и обновился до всех последних пакетов, а при попытке загрузить sample_resource в браузер и многократно нажимая его с помощью httpie, периодически появлялась ошибка сбоя рабочего процесса ( например, запрос будет отложен, и тогда я увижу ошибку; если бы я не отменил запрос, он в конечном итоге ответил бы). Это произошло только с рабочим классом синхронизации по умолчанию. Когда я указал использовать gevent, все заработало.

Спасибо, @ jhillhouse92 , попробую.

Я продолжаю видеть проблемы с таймаутами, @tilgovi. Завтра я займусь этим более подробно и опубликую обновление с более точной информацией. Пожалуйста, оставьте этот вопрос открытым; вы правы в том, что может происходить множество проблем, но общая тема заключается в том, что у рабочих Gunicorn (возможно, только с классом sync worker, tbd) возникают проблемы с тайм-аутом при использовании Gunicorn с приложением, развернутым с помощью AWS / ELB. Здесь что-то не так, даже если мы не выделили точную проблему. Стоит копать дальше. Завтра обновлю.

Стоит отметить, что я столкнулся с этой проблемой локально, а не в Docker / AWS / ELB, с упомянутым выше стеком.

Итак, я использую gevent, пытаюсь записать журналы доступа и пытаюсь развернуть свое приложение с помощью AWS / ELB.

команды 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"]

Я получаю сумасшедшие ошибки OOM в отношении кода ошибки 14, независимо от того, какие ограничения я установил. Кто-нибудь еще видел это в контексте этой проблемы? Раньше я мог видеть таймауты рабочих. С моими текущими конфигурациями я не могу воспроизвести таймауты / зайти так далеко.

[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

Повторюсь, я не вижу этого локально без докера. Я не вижу этого локально с Docker. Это, а также проблемы с тайм-аутом, очевидно, появляются только в стеке Docker / AWS / ELB (для меня).

@tilgovi Одна вещь, которую я изначально сделал неправильно (как видно из фрагмента, который я опубликовал выше), - это то, что у меня был ошибочно установлен тайм-аут 10 секунд. После изменения этого значения на 75 секунд количество тайм-аутов рабочих значительно сократилось, возможно, до пары в день. Для полноты картины это точная команда, которую я использую для запуска нашего приложения:

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

Файл .ini выглядит так:

[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

Объем трафика не играет роли - я вижу, что это происходит в нашей среде контроля качества, которая видит очень мало трафика.

Глядя на то, как часто это происходит, мне интересно, может ли это быть связано с перезапусками приложений?

У меня в чем-то похожая проблема. После некоторых расследований я думаю, что это, вероятно, ошибка сетевого подключения, а не стрельба.

Вот моя установка:

  • Сервер Postgresql работает на Docker на EC2. Образ докера - это официальная версия postgres 9.6.
  • Сервер приложений работает на Docker на виртуальной машине за пределами EC2. Образ докера - это официальный Python 3.6.
  • В группе безопасности AWS открыт только порт 5432 / tcp.

Как ни странно, большинство запросов от сервера приложений к серверу postgres были в порядке, кроме одного. Этот запрос, кажется, выполняется вечно, что приводит к таймауту рабочего времени.

Проблема исчезнет, ​​если я использую приложение локально.

Проблема также исчезнет, ​​если я не докерирую сервер приложений.

Мое временное исправление - открыть все соединения между сервером приложений и сервером postgres через настройку группы безопасности AWS. Теперь все снова работает нормально.

Я предполагаю, что между контейнером Python и AWS есть проблема с подключением. Я обновлюсь после тщательного изучения потока журналов AWS.

Спасибо!! Смена протокола ELB и Instance с HTTP на TCP работала нормально 👍

Проблема кажется не специфичной для AWS, а для самого Docker в сочетании с Gunicorn. Я вижу это и с gevent , по крайней мере, в нашей производственной среде.

@tilgovi Вот простое приложение для воссоздания этой ошибки (время от времени не находил шаблон, возможно, вы могли бы):

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"]

Для запуска: docker build -t gunicorn-and-docker . && docker run -p 8000:8000 -it --rm gunicorn-and-docker

Журналы будут выглядеть так (по крайней мере, для меня в macOS Sierra с использованием 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

Привет,

Я недавно столкнулся с той же проблемой.
В моем случае (ECS + gunicorn 19.7.1 + Django 1.11.5) мне (по-видимому) удалось решить эту проблему, просто увеличив объем памяти, выделенной для контейнера в определении задачи (со 128 до 256 МБ).
Пока ошибок больше нет. Я сообщу здесь, если это повторится.

Здесь немного добавлений к припеву, но я смог решить эту проблему, только переключившись на gevent.

Я попытался увеличить тайм-аут до 90 и keepalive до 75 с помощью синхронизатора, но безуспешно.

Кроме того, что интересно, мой ELB в этом сценарии выполняет только пересылку на уровне TCP, а не HTTP.

Хорошо, я нашел несколько ссылок, которые это объясняют. [1]

Это можно было решить с помощью небольших изменений на стороне Gunicorn. Если в синхронизирующем воркере после принятия нового соединения мы вызвали select() с коротким таймаутом, тогда мы могли бы обработать эти соединения. Это может быть немного сложно, особенно с несколькими сокетами для прослушивания. Самым простым было бы установить тайм-аут для первого байта. Я также не уверен, как это будет взаимодействовать с SSL.

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

Если вы столкнулись с этим и не хотите использовать gevent / eventlet / asyncio, я рекомендую переключиться на многопоточного воркера (укажите параметр --threads ).

@tilgovi Проблема, похоже, существует и с gevent worker, если вы посмотрите на мой пример выше.

@jmagnusson ваш пример (из этого комментария: https://github.com/benoitc/gunicorn/issues/1194#issuecomment-331740187), похоже, использует синхронизатора.

[2017-09-23 22:31:00 +0000] [1] [ИНФОРМАЦИЯ] Использование worker: sync

@tilgovi Верно, но я испытал это и с рабочим gevent в продакшене. Я постараюсь найти время для воспроизведения с помощью gevent.

Это может быть только я (глупо), но в группе безопасности EC2 -> правила для входящего трафика у меня есть настраиваемое правило TCP для порта 5000 (здесь пулеметчик), чтобы разрешить только один IP (мой IP: XX.XX.XX.XX / 32), изменение этого адреса на все IP поможет.

Я тоже сталкиваюсь с проблемой.

[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. 

Я добавил журнал отладки worker pid {WORKER_PID} notify .

Согласно журналу отладки,

  1. Уведомление не будет продолжаться только в том случае, если рабочий процесс получит один запрос. Таким образом, независимо от того, есть запросы или нет, мастер завершит рабочий процесс через 30 секунд.
  2. Как только первый запрос был закрыт, я отправил второй прямо сейчас, но второй запрос заблокирован и нет ответа. Когда истечет 30-секундный тайм-аут, рабочий процесс будет остановлен, и новый рабочий процесс ответит на второй запрос. Потом сервер снова завис.
  3. Когда рабочий процесс завис, он не получит сигнал от мастера, например SIGTERM . Когда истечет грациозный тайм-аут, мастер принудительно уничтожит его с помощью SIGKILL .
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

ВНИМАНИЕ: когда я использую eventlet в качестве рабочего, все в порядке.

Я собираюсь закрыть этот выпуск, так как считаю его устаревшим. Насколько я могу судить, наблюдаемое поведение связано с тем, что классические балансировщики нагрузки AWS выполняют предварительную оптимизацию. Эта оптимизация выполняется только классическими балансировщиками нагрузки, согласно документации о том, как работает балансировка нагрузки . Переключение на балансировщики нагрузки приложений должно решить проблему. Кроме того, как описано в этом сообщении в

@tilgovi FWIW Я видел это с ALB. Я никогда не использовал классические балансировщики нагрузки.

@tilgovi Я тоже неоднократно наблюдал это в средах только с ALB, никогда не использовал классику. Мы продолжали видеть это даже с поправкой на тайм-аут рабочего.

@tilgovi Я с этим встречался. Я никогда не пользовался AWS.

Кто-то должен помочь воспроизвести это и попытаться отладить это. Я не могу воспроизвести его с помощью ALB, и я не вижу, как воспроизвести его за пределами AWS.

@xgfone , возможно, вы захотите открыть свой собственный выпуск, название этого выпуска - «docker + AWS».

Кто-нибудь испытывал это с балансировщиками нагрузки AWS, но без Docker? Я немного запуталась, признаюсь :)

У меня сложилось впечатление, что проблема была больше связана с Docker - по крайней мере, у меня были точно такие же проблемы с запуском нескольких рабочих синхронизации gunicorn внутри Docker на моем локальном компьютере.

Эта конфигурация отлично работала без Docker на машинах Ubuntu и RHEL, как на голом железе, так и виртуализированных в Digital Ocean:

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

Внутри Docker (также RHEL, все остальное то же самое) рабочие всегда выходили из строя и постоянно перезапускались. Взяв рекомендации из этой ветки, я переключился на это, что отлично работает:

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

Если вы думаете, что это не имеет отношения к этой теме, я счастлив удалить его отсюда и поместить в другое место ;-)

С уважением, Борис

@tilgovi

Эта ошибка возникает в arbiter.py, murder_workers . Функция murder_workers вызывается, когда SIG_QUEUE пуст (например, при ожидании сигналов).

Затем он будет проверять, истек ли тайм-аут каждую секунду. Оставшееся время жизни всегда составляло 1 или 0 секунд, потому что работник gevent находится в управляемом бесконечном цикле, в то время как self.alive вызывает self.notify который обновляет файл. Обновления файла - это то, как gunicorn проверяет, когда произошло последнее активное время.

Таким образом, единственный способ проверки времени в реальном времени в функции murder_workers терпит неудачу (например, говорит, что она слишком долго простаивает) - это изменение свойства gevent alive. Следующие методы контролируют это:

handle_quit
handle_request (если было получено максимальное количество запросов, по умолчанию это 2 ^ 64 бит количества запросов или 2 ^ 32 в 32-битной ОС)
changed (вызывается из перезагрузчика, если файл был изменен)
handle_exit
handle_abort

Эти методы вызываются из сигналов

handle_quit - ПОДПИСАТЬ, ПОДПИСАТЬ
handle_exit - SIGTERM
handle_abort - SIGABRT

Таким образом, я вижу две возможные проблемы:

  1. Метод уведомления не может обновить файл во время его цикла
  2. Сигнал отправляется неправильно

Думаю, более вероятная причина - вторая. Основной источник сигналов находится в файле арбитра и запускается следующими исключениями:

  • StopIteration
  • KeyboardInterrupt
  • HaltServer
  • Exception (необработанное исключение)

Я думаю, что исключение StopIteration, скорее всего, вызвано в файле async.py по адресу req = six.next(parser) . Похоже, что следующий метод просто вызывает parser.next ().

Parser.next() вызывает исключение StopIteration при следующих двух условиях:

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

Я не уверен, что именно могло вызвать это непреднамеренно, но из 62 комментариев с этой проблемой, наблюдаемой в нескольких приложениях и средах, я думаю, что это стоит изучить дальше и рекомендовать повторно открыть его, или если нам не нравится название , создайте новую глобальную проблему с критическим отключением работников.

Я снова открою это и попробую проверить эти комбинации:

  • Докер локальный
  • Docker AWS с классическим балансировщиком нагрузки
  • Docker AWS с балансировщиком нагрузки приложений

Если кто-то хочет создать репо, которое может воспроизвести это, это было бы полезно, но я, вероятно, смогу сделать это в эти выходные.

У меня возникла эта проблема, и я не использую AWS.
Моя установка - это NGINX -> Docker container (Gunicorn с gevent worker + Django). Я использую тайм-ауты Gunicorn по умолчанию.

Какие-нибудь советы?

Спасибо.

Привет @davidmir!
У меня была такая же проблема, смена типа воркера не помогла. Переключение на одного синхронизатора с несколькими потоками помогло мне:

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

С уважением, Борис

Хотя некоторые из них упоминались выше, чтобы прояснить мою собственную отладку этой проблемы, некоторые из них связаны с ошибками нехватки памяти; особенно, если это решается путем изменения счетчика рабочих до 1.

Это особенно проблематично в Docker, если в вашей конфигурации есть что-то вроде этого:

workers = multiprocessing.cpu_count() * 2 + 1

Но ограничивают доступную для контейнера память; синхронный рабочий запускает несколько потенциально тяжелых интерпретаторов Python. Обратите внимание, что количество ЦП основано на общем количестве ЦП машины, а не на том, что вы подготовили для использования докер-контейнером; если вы используете ограниченный контейнер, вы должны вместо этого основывать подсчет рабочих.

Хотя это варьируется от приложения к приложению, мое эмпирическое правило - 256 мегабайт на одного рабочего в упрощенной конфигурации и 512 в целях безопасности.

Столкнулся с той же проблемой при использовании Classic ELB HTTPS => HTTP Gunicorn Sync Workers

Как уже упоминалось, самым простым решением было использование аргумента -k gevent вместо рабочего синхронизатора по умолчанию.

Мы увидели, что та же проблема возникла снова для совершенно нового контейнера Docker (размещенного в ECS за ALB), и нашли совершенно другое (но задним числом должно было быть очевидным) решение: выделить больше памяти для контейнера в CloudFormation. шаблон.

В прошлом году мы столкнулись с этой проблемой и так и не нашли первопричину дымящегося пистолета, но сегодня вечером я обнаружил ее на новом контейнере и случайно заметил, что контейнер поглощает всю выделенную память. Как только я удвоил выделение, контейнеры перестали выдавать эту ошибку (даже до того, как я выделил больше, чем в конечном итоге потреблял):
https://github.com/hackoregon/civic-devops/issues/157

Здесь возникает аналогичная проблема. код так же прост, как

while true:
      sleep(10)

может привести к смерти рабочего (без этого кода наше развертывание является нормальным)
это очень озадачивает, b / c sleep должен послать сердцебиение.

тоже уже поменял на gevent, не помогло. Интересно, есть ли у кого-нибудь мысли?

образец вывода:
[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

Извините за мутность здесь, но просто хотел поделиться своим опытом, мой стек HTTP ELB > Nginx > gunicorn/gevent on EC2 , процессы выполняются с использованием circusd

Проблема, которую я обнаружил, заключалась в том, что после инструментирования моего приложения django с помощью elastic-apm мои HTTP-проверки работоспособности начали давать сбой почти сразу, и gunicorn перестал отвечать через несколько секунд.

Я попробовал несколько локальных тестов wrk моей проверки работоспособности, синхронизация давала около 300 оборотов в секунду для 1-5 рабочих, но gevent получил 1 запрос в секунду. Отключение apm увеличило gevent примерно до 50 оборотов в секунду и незначительное увеличение для синхронизации.

Не заметил какого-либо странного использования памяти на valgrind, обычно около 4 МБ для Gunicorn и 40 МБ на воркера

В любом случае, обновление gunicorn 19.6.0 > 19.9.0 и gevent 1.2.2 > 1.3.6 снова дает мне отличную проверку работоспособности ELB и ~ 300 оборотов в секунду локально. Я сознательно не обновлял gunicorn / gevent до тех пор, пока у меня не было некоторого журнала APM, похоже, это вызвало некоторую интуицию. По понятным причинам обновление gevent дало наибольший прирост, но затем обновление Gunicorn, похоже, прибавило еще 10% или около того.

Еще не просмотрели детально журналы изменений, возможно, сопровождающие смогут пролить свет на наиболее вероятную причину?

В любом случае, обновление gunicorn 19.6.0> 19.9.0 и gevent 1.2.2> 1.3.6 снова дает мне отличную проверку работоспособности ELB и ~ 300 оборотов в секунду локально .... Обновление gevent дало наибольший импульс

Вау, это круто!

закрытие вопроса. нет активности с некоторого времени.

FWIW, у меня все еще проблема @benoitc : - \

Django 2.1.5
Gunicorn 19.8.1
gevent 1.2.2
AKS 1.15.7 с 5 узлами (стандартные B2 - 2 виртуальных ядра и 2 ГБ памяти)
3 pod / docker-контейнера, в каждом из которых есть:

    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"

Та же проблема здесь с EKS, Nginx и NLB.

@salmicrosoft @sinkr Хорошо, но, пожалуйста, откройте новую проблему и предоставьте все имеющиеся у вас журналы, которые могут помочь нам понять, что происходит. И что делает ваше приложение? У вас есть длинный запрос?

У меня была такая же проблема с ECS Fargate, но она была связана с неправильными настройками keepalive / timeout в Docker / gunicorn.conf.py, это было
keepalive (не установлен)
тайм-аут = 2

До исправления он хорошо работал с контейнером, работающим локально, но не работал на ECS Fargate, теперь он работает правильно в обеих средах.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги