Помилка таймауту працівника гунікорна


182

У мене є установка гармати з трьома працівниками 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 (І не витончений тайм-аут). Це працює як годинник ..

То роби:

1) відкрити файл конфігурації guicorn

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

Запустити Гунікорн з --log-level=DEBUG.

Він повинен дати вам стежити за стеком додатків.


41
У моєму випадку це не так.
Джо

16
це зараз--log-level debug
psychok7

4
Я б хотів отримати прокладку, але жоден з них не працює тут, використовуючи рушницю 19.4.5. Відображається налагодження матеріалів, тому я здогадуюсь, прапор був розпізнаний, але не стек-трек на час очікування.
orzel


6

Вам потрібно скористатися іншим класом робітників типу асинхронного типу, наприклад, gevent або tornado, див. Це для отримання додаткового пояснення: Перше пояснення:

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

Другий :

Синхронні працівники за замовчуванням передбачають, що ваша програма пов'язана з ресурсами з точки зору пропускної здатності процесора та мережі. Як правило, це означає, що ваша програма не повинна робити нічого, що потребує невизначеного часу. Наприклад, запит в Інтернет відповідає цим критеріям. У якийсь момент зовнішня мережа вийде з ладу таким чином, що клієнти накопичуються на ваших серверах.


Як я б насправді скористався таким різним класом робітників?
Фредерік Норд

6

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

Тому я подумав, що це може бути проблемою з ресурсами, і я продовжував надавати інстанції більше оперативної пам’яті, і це спрацювало.


1
Я бачив цю проблему навіть з gevent та встановив тайм-аут, встановлений правильно, у пам'яті була проблема
bcattle

6

WORKER TIMEOUTозначає, що ваша програма не може відповісти на запит у визначений проміжок часу. Ви можете встановити це за допомогою налаштувань тайм-ауту . Деяким додаткам потрібно більше часу для відповіді, ніж іншим.

Інша річ, яка може вплинути на це - це вибір типу робітника

Синхронні працівники за замовчуванням припускають, що ваша програма пов'язана з ресурсами з точки зору пропускної здатності ЦП та мережі. Як правило, це означає, що ваша програма не повинна робити нічого, що потребує невизначеного часу. Прикладом чогось, що потребує невизначеної кількості часу, є запит в Інтернет. У якийсь момент зовнішня мережа вийде з ладу таким чином, що клієнти накопичуються на ваших серверах. Отже, у цьому сенсі будь-яка веб-програма, яка надсилає вихідні запити до 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

тайм-аут є ключовим параметром цієї проблеми.

проте це для мене не підходить.

Я виявив, що немає помилки тайм-ауту, коли я встановлюю робітників = 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.