Для чего нужны брокеры в Celery
Что проверяют
Понимаете ли вы, как задача физически попадает от веб-приложения к воркеру и где она может потеряться. Следом обычно спрашивают, чем брокер отличается от result backend и что будет, если воркер упадёт посреди задачи.
Как отвечать
Брокер это транспорт сообщений. Вызов task.delay() или apply_async() сериализует имя задачи и аргументы в сообщение и публикует его в очередь брокера. Воркеры забирают сообщения и выполняют. Веб-процесс не ждёт и не знает, какой воркер возьмёт работу.
Что это даёт:
- развязку: приложение и воркеры масштабируются и перезапускаются независимо;
- буфер: всплеск задач копится в очереди, а не роняет сервис;
- маршрутизацию: отдельные очереди для тяжёлых и быстрых задач через
task_routesи воркеры с ключом-Q.
Результаты брокер не хранит. Для них есть отдельный result backend (Redis, база через SQLAlchemy или Django ORM), и включать его стоит, только если результат действительно читают.
Стабильно поддерживаются RabbitMQ, Redis и Amazon SQS, работа с ними идёт через библиотеку Kombu. Настройка одной строкой: broker_url = "amqp://..." или "redis://...".
Про надёжность говорите конкретно. По умолчанию Celery подтверждает сообщение перед выполнением, и при падении воркера задача теряется. Чтобы подтверждение шло после выполнения, включают task_acks_late, а задачи делают идемпотентными, потому что возможен повтор. У Redis есть visibility_timeout (по умолчанию час): неподтверждённая задача вернётся в очередь, а задача с countdown дольше этого срока может выполниться дважды. Redis без персистентности теряет очередь при перезапуске.
Где спотыкаются
Путают брокер и result backend или считают, что брокер хранит результаты задач.
Говорят, что повторы при ошибке обеспечивает брокер. Ретраи делает Celery через autoretry_for или self.retry(), брокер лишь доставляет новое сообщение.
Утверждают, что брокер гарантирует сохранность задач. Без acks_late, персистентных очередей и идемпотентности задачи теряются или выполняются дважды.