Ответ
Celery взаимодействует с основным приложением асинхронно через брокера сообщений (например, RabbitMQ, Redis). Этот паттерн разделяет выполнение долгих задач от основного потока приложения, предотвращая его блокировку и улучшая отзывчивость.
Процесс выглядит так:
- Приложение-продюсер (Producer): Основное приложение вызывает задачу Celery (
task.delay()). Эта задача не выполняется немедленно, а сериализуется и отправляется как сообщение в очередь брокера. - Брокер сообщений (Broker): Хранит очередь сообщений (задач) до тех пор, пока их не заберет обработчик.
- Воркер Celery (Consumer): Отдельный процесс, который слушает очередь в брокере. Когда появляется новая задача, воркер забирает ее, выполняет и, опционально, сохраняет результат.
- Бэкенд результатов (Result Backend): Хранилище (например, Redis, база данных), куда воркер может записать результат выполнения задачи. Основное приложение может затем запросить этот результат.
Пример:
# tasks.py - код для воркера Celery
from celery import Celery
import time
# Инициализация Celery с указанием брокера и бэкенда
app = Celery('tasks',
broker='redis://localhost:6379/0',
backend='redis://localhost:6379/0')
@app.task
def process_data(x, y):
time.sleep(5) # Имитация долгой операции
return x + y
# main_app.py - код основного приложения
from tasks import process_data
# Асинхронный вызов задачи. Приложение не ждет 5 секунд.
task_result = process_data.delay(10, 20)
print(f"Задача отправлена. ID задачи: {task_result.id}")
# ... здесь приложение может выполнять другую работу ...
# Чтобы получить результат, можно использовать .get()
# Внимание: .get() - это блокирующий вызов!
result = task_result.get(timeout=10)
print(f"Результат получен: {result}")
Ключевые преимущества:
- Независимость: Основное приложение и воркеры Celery — это отдельные, независимо работающие процессы.
- Надежность: Брокер гарантирует доставку задач, даже если воркер временно недоступен.
- Масштабируемость: Можно легко добавить больше воркеров для обработки возросшей нагрузки.