Короткий ответ
Выбор зависит от характера задач (CPU-bound или I/O-bound), требуемой надёжности при сбоях (нужна ли устойчивость к падению процесса и повторные попытки), объёма и пиковости нагрузки, а также от готовности команды поддерживать дополнительную инфраструктуру (брокер сообщений, воркеры) в обмен на масштабируемость и изоляцию от основного процесса.
Как это работает подробнее
Встроенные потоки/процессы/asyncio-таски живут в рамках процесса приложения — просты в реализации, но при падении процесса незавершённые задачи и их состояние теряются без отдельного механизма персистентности. Выделенная очередь задач с брокером (Redis, RabbitMQ) хранит задачи вне процесса-исполнителя — воркер может упасть и перезапуститься, а задача останется в очереди и будет подхвачена снова.
- Компромисс. Встроенное решение проще в разработке и не требует дополнительной инфраструктуры, но не переживает перезапуск процесса и плохо масштабируется горизонтально; очередь задач с брокером даёт надёжность и масштабируемость, но добавляет операционную нагрузку (мониторинг брокера, воркеров, идемпотентность задач при повторной доставке) — выбор зависит от критичности задач для бизнеса, ожидаемой нагрузки и готовности команды поддерживать дополнительный компонент инфраструктуры.
Пример кода
example-281.txt
Сценарий А: внутренний инструмент, генерация PDF-отчёта по запросу пользователя, нечастые вызовы.
Решение: run_in_executor в рамках текущего процесса - просто, без лишней инфраструктуры.
Сценарий Б: отправка транзакционных писем о платежах, тысячи в час, нужна гарантия доставки.
Решение: очередь задач (Celery/RQ) с брокером, retry с экспоненциальной задержкой,
dead-letter очередь для задач, не выполнившихся после N попыток, мониторинг глубины очереди.Что использовать на практике
- Практика. Для коротких, нечастых и не особо критичных фоновых операций часто достаточно
run_in_executor/отдельного потока в рамках того же процесса. Для задач, которые должны гарантированно выполниться даже при сбоях (отправка писем о платежах), и там, где нужно горизонтальное масштабирование числа воркеров независимо от веб-процесса, обоснована выделенная очередь задач с персистентным брокером и механизмом retry/dead-letter.
Подводные камни
- Риски. Берут тяжёлую инфраструктуру очередей задач для простого прототипа без реальной потребности в надёжности при сбоях, увеличивая операционную сложность без выигрыша; встраивают критичную для бизнеса логику во встроенные потоки процесса, теряя задачи при любом перезапуске сервиса и не замечая это до инцидента.