JavaRush /Курсы /Модуль 4: FastAPI /Использование нескольких воркеров для распределения нагру...

Использование нескольких воркеров для распределения нагрузки

Модуль 4: FastAPI
14 уровень , 2 лекция
Открыта

В этой лекции мы подробно разберем, как использовать несколько воркеров для распределения нагрузки, как они взаимодействуют с RabbitMQ, а также как правильно мониторить и управлять их производительностью. Готовы? Тогда держите локтевые суставы расслабленными (для удобного нажатия на клавиши) и поехали!

Мы уже приводили пример с очередями в банке. Если вы когда-нибудь стояли в очереди в банке (а кто не стоял?), то знаете, что обслуживать клиентов быстрее можно только одним способом — открыть больше «окон». В мире асинхронных задач роль таких окон играют воркеры. Каждый воркер Celery — это отдельный процесс, который выполняет задачи, поступающие из очереди RabbitMQ.

Несколько воркеров — быстрее работа: задачи обрабатываются одновременно, система устойчивее (один воркер упадёт, остальные — продолжат работу). Ну и нагрузка равномернее распределена. Сплошная выгода!

RabbitMQ, как очередь сообщений, автоматически распределяет задачи между воркерами. Принцип тут простой: pull-модель, где воркеры сами «запрашивают» задачи у очереди. Например:

  • Воркеры A, B, C подключены к одной очереди.
  • Как только воркер A завершает задачу, он запрашивает следующую.
  • RabbitMQ выдаёт эту задачу первому воркеру, который запросит её.

Таким образом, задачи распределяются автоматически, без необходимости «говорить» RabbitMQ, кому что отправлять. Это похоже на столовую: повар готовит еду, а официанты берут подносы, как только освободятся.


Запуск нескольких воркеров

Запуск нескольких воркеров — это не магия и не шаманство. Всё, что вам нужно сделать, это создать несколько процессов, каждый из которых будет выполнять роли воркеров. Давайте посмотрим, как это сделать на практике.

Команда для запуска воркеров в Celery выглядит так:


celery -A my_project worker --loglevel=info

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

Celery позволяет указать количество процессов для одного воркера. Это делается с помощью флага --concurrency. Например:


celery -A my_project worker --loglevel=info --concurrency=4

Здесь:

  • --concurrency=4 означает, что один воркер создаст 4 процесса для выполнения задач.

Вы также можете запустить несколько отдельных воркеров:


celery -A my_project worker --loglevel=info --hostname=worker1@
celery -A my_project worker --loglevel=info --hostname=worker2@

Эти команды создадут два воркера с именами worker1 и worker2.


Примеры архитектуры с несколькими воркерами

Несколько воркеров полезны, если у вас:

  • Большое количество входящих задач.
  • Разные задачи требуют различных ресурсов.
  • В системе имеются задачи с высоким приоритетом.

Например, в e-commerce системе могут быть задачи:

  • Обработка заказов.
  • Отправка email-уведомлений.
  • Генерация отчетов.

Логично разделить такие задачи между разными воркерами: один будет обрабатывать только email, другой — заказы, а третий займется отчётами.

Пример распределения задач

Создадим два воркера: один для задач с высоким приоритетом, второй — для низкоприоритетных.

  1. В настройках Celery указываем две очереди:

from kombu import Queue

CELERY_QUEUES = (
    Queue('high_priority', routing_key='high.#'),
    Queue('low_priority', routing_key='low.#'),
)

CELERY_ROUTES = {
    'tasks.process_order': {'queue': 'high_priority', 'routing_key': 'high.orders'},
    'tasks.send_email': {'queue': 'low_priority', 'routing_key': 'low.emails'},
}
  1. Запускаем два воркера с привязкой к очередям:

celery -A my_project worker --loglevel=info --queues=high_priority --hostname=worker_high@
celery -A my_project worker --loglevel=info --queues=low_priority --hostname=worker_low@

Теперь задачи будут распределяться в зависимости от их приоритета.


Настройка и мониторинг воркеров

Celery имеет встроенные инструменты для мониторинга. Команда celery status показывает текущих активных воркеров:


celery -A my_project status

Вывод может выглядеть так:


celery@worker_high: OK
celery@worker_low: OK

Другие полезные команды:

  • celery inspect active — показывает текущие задачи, выполняемые воркерами.
  • celery inspect reserved — задачи, ожидающие выполнения.
  • celery inspect stats — статистика работы, включая количество обработанных задач.

Использование Flower для мониторинга

А ещё у Celery есть инструмент Flower — визуальный интерфейс для мониторинга.

  1. Установите Flower:

pip install flower
  1. Запустите Flower:

celery -A my_project flower
  1. Откройте браузер и перейдите по адресу: http://localhost:5555.

Flower покажет информацию о всех ваших воркерах, очередях и задачах в реальном времени.


Инструменты управления воркерами

Иногда нужно перезапустить воркеры. Например, если вы обновили код задач. Используйте команду:


pkill -HUP -f 'celery worker'

Эта команда мягко перезапустит все воркеры. Если вы хотите принудительно завершить их работу:


pkill -9 -f 'celery worker'

Управление ресурсами воркеров

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

  • --concurrency=N — количество процессов.
  • --prefetch-multiplier=X — количество задач, которые воркер берёт в работу одновременно.
  • --max-tasks-per-child=N — ограничивает число задач, которые может выполнить процесс воркера перед завершением.

Пример запуска:


celery -A my_project worker --concurrency=4 --prefetch-multiplier=1 --max-tasks-per-child=100

Здесь:

  • Каждому процессу выдаётся только одна задача (для минимизации использования памяти).
  • Процесс завершится после 100 задач, чтобы избежать накопления утечек памяти.

Заключительный пример

Давайте создадим воркеров для системы обработки данных. Пусть у нас есть задачи:

  1. Запись данных в базу данных.
  2. Отправка уведомлений.

Создадим отдельные очереди и воркеры:


CELERY_ROUTES = {
    'tasks.save_to_db': {'queue': 'db_queue'},
    'tasks.send_notification': {'queue': 'notifications_queue'},
}

Запуск воркеров:


celery -A my_project worker --loglevel=info --queues=db_queue --hostname=worker_db@
celery -A my_project worker --loglevel=info --queues=notifications_queue --hostname=worker_notifications@

Теперь worker_db будет обрабатывать задачи записи в БД, а worker_notifications — задачи отправки уведомлений. Эффективно и красиво!


Разделение задач между воркерами и очередями — мощный инструмент для повышения производительности системы. В зависимости от нагрузки вы можете добавлять или удалять воркеры, делать их более «умными» с QoS, а также управлять распределением задач с помощью маршрутов.

Теперь вам остаётся только попробовать запустить свои воркеры, а если что-то пойдёт не так... даже лучшие инженеры сталкивались с этим. Главное — не сдаваться!

1
Задача
Модуль 4: FastAPI, 14 уровень, 2 лекция
Недоступна
Запуск нескольких воркеров
Запуск нескольких воркеров
1
Задача
Модуль 4: FastAPI, 14 уровень, 2 лекция
Недоступна
Разделение задач по очередям
Разделение задач по очередям
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ