Ошибка тайм-аута рабочего Gunicorn


182

Я установил gunicorn с 3 рабочими, 30 рабочими соединениями и использую рабочий класс Eventlet. Это настройка позади Nginx. После каждых нескольких запросов я вижу это в журналах.

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

Почему это происходит? Как я могу понять, что происходит не так?

Спасибо


2
Вы смогли решить проблему? Пожалуйста, поделитесь своими мыслями, как я тоже придерживался этого. Gunicorn==19.3.1иgevent==1.0.1
Black_Rider

2
Нашел решение для этого. Увеличено время ожидания до очень большого значения, и затем я смог увидеть трассировку стека
Black_Rider

Ответы:


156

У нас была та же проблема с использованием Django + nginx + gunicorn. Из документации Gunicorn мы настроили изящный таймаут, который почти не изменился.

После некоторых испытаний мы нашли решение, параметр для настройки: timeout (а не graceful timeout). Работает как часы ..

Ну действуй:

1) открыть файл конфигурации gunicorn

2) установите TIMEOUT на то, что вам нужно - значение в секундах

NUM_WORKERS=3
TIMEOUT=120

exec gunicorn ${DJANGO_WSGI_MODULE}:application \
--name $NAME \
--workers $NUM_WORKERS \
--timeout $TIMEOUT \
--log-level=debug \
--bind=127.0.0.1:9000 \
--pid=$PIDFILE

9
Спасибо, это правильный ответ. И затем, для того, чтобы сохранить ресурсы с множеством одновременных подключений:, pip install geventзатем worker_class geventв вашем конфигурационном файле или -k geventв командной строке.
little_birdie

2
Я работаю с супервизором, поэтому добавил его в conf.d / app.conf :command=/opt/env_vars/run_with_env.sh /path/to/environment_variables /path/to/gunicorn --timeout 200 --workers 3 --bind unix:/path/to/socket server.wsgi:application
lukik


21

Запустите Gunicorn с --log-level=DEBUG.

Это должно дать вам трассировку стека приложений.


41
Это не в моем случае.
Джо

16
это сейчас--log-level debug
psychok7

4
Я хотел бы получить трассировку, но никто из них не работает здесь, используя gunicorn 19.4.5. Отладочные данные отображаются, поэтому, я думаю, флаг был распознан, но не отслеживание стека по тайм-ауту.
orzel


6

Вы должны Использовали другой класс типа работника в асинхр один как GEvent или торнадо увидеть это более подробное объяснение: Первый explantion:

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

Второй :

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


Как бы я на самом деле использовал такой другой рабочий класс?
Фредерик Норд,

6

У меня была очень похожая проблема, я также пытался использовать "runserver", чтобы посмотреть, смогу ли я найти что-нибудь, но все, что у меня было, это сообщение Killed

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


1
Я видел эту проблему даже с gevent и тайм-аутом, установленным правильно,
нехватка

6

WORKER TIMEOUTозначает, что ваше приложение не может ответить на запрос в течение определенного периода времени. Вы можете установить это, используя настройки тайм-аута Gunicorn . Некоторое приложение требует больше времени для ответа, чем другое.

Еще одна вещь, которая может повлиять на это, это выбор типа работника.

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

Когда у меня возникла та же проблема, что и у вас (я пытался развернуть свое приложение с помощью Docker Swarm), я попытался увеличить время ожидания и использовать другой тип рабочего класса. Но все не удалось.

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

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

Поэтому я предлагаю вам проверить, что замедляет работу вашего приложения.


4

Эта конечная точка занимает слишком много времени?

Возможно, вы используете колбу без асинхронной поддержки, поэтому каждый запрос будет блокировать вызов. Чтобы создать асинхронную поддержку без трудностей, добавьтеgevent рабочий.

С Gevent новый вызов будет порождать новый поток, и ваше приложение сможет получать больше запросов

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

1
простой твик .. спас мой день!
penduDev

3

У меня такая же проблема в Докере.

В Docker я держу обученную LightGBMмодель + Flaskобслуживание запросов. В качестве HTTP-сервера я использовал gunicorn 19.9.0. Когда я запускал свой код локально на своем ноутбуке Mac, все работало просто отлично, но когда я запустил приложение в Docker, мои запросы POST JSON на некоторое время зависали, а затем gunicornрабочий отказывал за [CRITICAL] WORKER TIMEOUTисключением.

Я перепробовал множество разных подходов, но единственное, что решило мою проблему - добавление worker_class=gthread.

Вот мой полный конфиг:

import multiprocessing

workers = multiprocessing.cpu_count() * 2 + 1
accesslog = "-" # STDOUT
access_log_format = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(q)s" "%(D)s"'
bind = "0.0.0.0:5000"
keepalive = 120
timeout = 120
worker_class = "gthread"
threads = 3

проголосовал за некоторые из ваших других ответов, но только этого недостаточно: P
Achala Dissanayake


1

Тайм-аут является ключевым параметром этой проблемы.

Однако это не подходит для меня.

я обнаружил, что нет ошибки тайм-аута gunicorn, когда я установил работников = 1.

когда я смотрю через мой код, я обнаружил некоторое соединение с сокетом (socket.send & socket.recv) в init сервера.

socket.recv заблокирует мой код, и поэтому всегда, когда рабочие> 1

надеюсь дать некоторые идеи людям, которые имеют некоторые проблемы со мной


1

Это сработало для меня:

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

Если у вас есть eventletдобавить:

--worker-class=eventlet

Если у вас есть geventдобавить:

--worker-class=gevent

0

Для меня решение было добавить --timeout 90к моей точке входа, но она не работала, потому что у меня были определены две точки входа, одна в app.yaml, а другая в моем Dockerfile. Я удалил неиспользованную точку входа и добавил --timeout 90в другую.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.