Очередь задач (Task Queue) — паттерн асинхронной обработки в серверных приложениях. Вместо того чтобы выполнять тяжёлые операции синхронно (заставляя пользователя ждать), приложение помещает задачу в очередь и немедленно возвращает ответ. Отдельные процессы-воркеры (workers) забирают задачи из очереди и обрабатывают их в фоне.
Как работает очередь задач
Архитектура типичной системы очередей:
- Producer — приложение, добавляющее задачи в очередь
- Broker — хранилище очереди (Redis или RabbitMQ)
- Worker — процесс, забирающий и выполняющий задачи
- Result Backend — хранение результатов выполнения
Популярные реализации:
- Celery (Python) + Redis/RabbitMQ — де-факто стандарт для Python-проектов
- Bull/BullMQ (Node.js) + Redis — для JavaScript-бэкенда
- Sidekiq (Ruby) + Redis — для Rails-приложений
- Horizon (PHP/Laravel) + Redis — для Laravel
Пример использования Celery: пользователь загружает изображение → Django сохраняет файл и добавляет задачу resize_image.delay(file_id) в Redis → сразу возвращает HTTP 202 → воркер Celery забирает задачу, обрабатывает изображение → результат сохраняется в БД.
История
Message queues появились в корпоративных системах в 1980-х (IBM MQ Series). Для веб-разработки паттерн стал массовым в 2000-х с ростом нагрузок. Celery выпущен в 2009 году и быстро стал стандартом Python-сообщества. RabbitMQ (2007) и Redis как брокер (2010-е) дали разработчикам простые инструменты для реализации очередей без enterprise-сложности.
На что обращать внимание
Длина очереди и время ожидания задач — ключевые метрики. Если очередь растёт быстрее, чем воркеры успевают её обрабатывать — нужно масштабировать количество воркеров или оптимизировать их. Инструменты мониторинга: Flower (для Celery), Bull Board (для BullMQ), Grafana с метриками Redis.
Важно правильно обрабатывать ошибки: задачи должны быть идемпотентными (повторное выполнение не даёт побочных эффектов), настройте механизм retry с экспоненциальным backoff. Redis как брокер прост в настройке, но не гарантирует доставку при падении сервера без включённого persistence. Для критически важных задач используйте RabbitMQ или настройте Redis AOF.
Развёртывание очереди задач на сервере
Для production-деплоя очереди задач нужно учесть несколько аспектов. Воркеры должны запускаться как системные сервисы через systemd или Docker — чтобы автоматически перезапускались при падении.
Пример systemd unit для Celery:
[Unit]
Description=Celery Worker
After=network.target redis.service
[Service]
User=www-data
WorkingDirectory=/var/www/myapp
ExecStart=celery -A myapp worker -l info -c 4
Restart=always
[Install]
WantedBy=multi-user.target
Параметр -c 4 запускает 4 параллельных воркера. Количество воркеров зависит от характера задач: CPU-интенсивные задачи — количество ядер, IO-интенсивные (сетевые запросы, работа с файлами) — в 2–4 раза больше ядер.
Мониторинг очереди критически важен: если задачи накапливаются быстрее обработки, это ведёт к росту latency и потенциальной потере задач при рестарте брокера. Grafana с метриками Redis (длина очереди, время обработки) помогает обнаружить проблемы заблаговременно. При горизонтальном масштабировании — добавляйте воркер-ноды, не увеличивайте брокер: Redis легко справляется с тысячами задач в секунду.