Celery — це бібліотека, яка дозволяє організувати виконання фонових (ще називають «асинхронними») задач у Python‑застосунках. Наприклад, якщо ви хочете відправити листа користувачу, обробити зображення або зробити складний розрахунок, вам не потрібно змушувати користувача чекати завершення цих операцій. Замість цього ви можете перемістити такі задачі у фон, щоб вони виконувалися окремо від основного потоку вашого застосунку.
Побачили фразу «фонова задача» і уявили якусь магію? Ні, нічого надприродного. Celery, як досвідчений офіціант, бере на себе ті дії, які не вимагають нашої негайної уваги, наприклад:
- Обробка великого обсягу даних.
- Відправка сповіщень та листів.
- Генерація звітів.
- Робота з зовнішніми API.
Архітектура Celery
Архітектура Celery будується навколо трьох основних компонентів:
- Продюсери — це застосунки, які створюють задачі для обробки. У нашому випадку це FastAPI або Django.
- Брокери повідомлень — черга задач, де задачі очікують свого виконання. Зазвичай для цього використовують RabbitMQ або Redis.
- Воркери — це процеси, які виконують задачі. Вони запускаються у фоновому режимі і виконують задачі, які продюсери додають у чергу.
FastAPI/Django (продюсер) -> RabbitMQ/Redis (брокер) -> Celery воркер (виконання задач)
Основні можливості Celery
Celery — це справжній швейцарський ніж для розробника. Ось кілька ключових можливостей:
Підтримка різних брокерів повідомлень
Celery може працювати з різними брокерами повідомлень. Найпопулярніші:
- RabbitMQ — потужний брокер з підтримкою складних сценаріїв маршрутизації задач.
- Redis — інтуїтивно зрозумілий і легкий брокер, який чудово підходить для швидкого старту.
Брокер гарантує, що ваша задача не загубиться, навіть якщо сервер раптово впаде. Так, це як каска у Python — захищає ваш проєкт від серйозних проблем.
Як RabbitMQ розуміє, що повідомлення оброблене
Постійні черги хороші тим, що зберігають повідомлення навіть після перезапуску сервера. Але щоб зробити систему дійсно надійною, треба ще потурбуватися про те, щоб RabbitMQ знав: «Це повідомлення точно оброблене, можна його більше не зберігати». Для цього використовується підтвердження доставки — acknowledgement.
RabbitMQ дозволяє вручну підтверджувати, що повідомлення успішно оброблене. Поки ви цього не зробили, воно залишається в черзі — і якщо ваш консьюмер раптом зламається, повідомлення не пропаде, а просто потрапить до іншого обробника. Це особливо важливо, коли йдеться про критичні дані, типу платежів або замовлень.
Ось приклад простого консьюмера, який обробляє повідомлення з durable‑черги і явно підтверджує кожне з них:
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
channel.queue_declare(queue='durable_queue', durable=True)
def callback(ch, method, properties, body):
print(f"Отримано повідомлення: {body}")
# Підтверджуємо, що все добре і повідомлення можна видалити
ch.basic_ack(delivery_tag=method.delivery_tag)
channel.basic_consume(queue='durable_queue', on_message_callback=callback, auto_ack=False)
print("Очікування повідомлень. Натисніть CTRL+C для виходу.")
channel.start_consuming()
Тут важливо, що auto_ack=False — це означає, що повідомлення не зникне, допоки ми не скажемо «все, готово» за допомогою basic_ack. Такий підхід дає впевненість, що жодне важливе повідомлення не загубиться навіть при збоях.
Приклади реальних задач для Celery
Щоб зрозуміти, наскільки корисний Celery, давайте глянемо на приклади:
- Відправка сповіщень та листів: уявіть застосунок для відправки e‑mail. З Celery ви можете відправляти листи асинхронно, не гальмуючи роботу основного потоку.
- Обробка зображень: наприклад, у соціальному застосунку користувачі завантажують зображення, які потрібно стиснути або накласти водяний знак. Celery відмінно справиться з таким завданням.
- Генерація звітів: у системах аналітики Celery може генерувати звіти за певні періоди.
- Робота з зовнішніми API: якщо ваш сервер має інтегруватися з повільними API, ви можете робити це асинхронно.
Як Celery виконує всю роботу?
Давайте розберемо життєвий цикл задачі в Celery:
- У вашому коді ви «запаковуєте» завдання. Це може бути задача, яка обробляє зображення або відправляє лист.
- Celery передає задачу в брокер повідомлень (наприклад, RabbitMQ).
- Брокер повідомлень зберігає задачу в черзі до того моменту, поки воркер не стане вільним.
- Воркер бере задачу з черги і виконує її.
- Після завершення задачі воркер може зберегти результат (наприклад, у базі даних).
Ось так просто Celery бере складну задачу і розбиває її на зрозумілі етапи, щоб жоден компонент системи не перевантажувався.
Давайте напишемо свій перший код з Celery
Для початку потрібно встановити Celery. Запускаємо таку команду:
pip install celery
Якщо ви плануєте використовувати Redis як брокер повідомлень, встановіть додаткові залежності:
pip install redis
Мінімальний приклад
Створимо файл tasks.py:
# tasks.py
from celery import Celery
# Створюємо додаток Celery
app = Celery('example', broker='redis://localhost:6379/0')
@app.task
def add(x, y):
return x + y
Після цього запустимо воркер:
celery -A tasks worker --loglevel=info
Тепер у Python‑консолі ми можемо викликати задачу асинхронно:
>>> from tasks import add
>>> result = add.delay(4, 6)
>>> print(result.get()) # Очікуємо результат
10
Цей приклад показує, як просто створювати і запускати фонові задачі за допомогою Celery.
Переваги і недоліки використання Celery
Переваги:
- Простота використання та гнучкість.
- Підтримка великої кількості брокерів.
- Велика спільнота і багато документації.
- Асинхронність підвищує продуктивність системи.
Недоліки:
- Потрібна окрема інфраструктура для брокера (наприклад, RabbitMQ або Redis).
- Можуть виникати складнощі з моніторингом і налагодженням (але для цього є інструменти, як Celery Flower).
У наступній лекції ми навчимося розгортати Celery у реальних проєктах на Django і FastAPI. Подивимося, як інтегрувати Celery у існуючі проєкти і перевіримо його на практиці. Готуйтесь до кодування!
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ