Django та Celery: асинхронна обробка завдань і питання для співбесід 2026
Повний гайд з інтеграції Django та Celery: налаштування, маршрутизація завдань, Celery Beat, Flower, продакшн-конфігурація та питання для співбесід 2026.

Сучасні веб-додатки на Django рідко обходяться без асинхронної обробки завдань. Відправка електронних листів, генерація звітів, обробка зображень, синхронізація з зовнішніми API — усі ці операції блокують HTTP-відповідь і погіршують досвід користувача. Celery залишається найпопулярнішим рішенням для фонової обробки завдань у Django-проєктах, і глибоке розуміння цього інструменту є обов'язковим для розробників, які претендують на позиції middle та senior рівня у 2026 році.
У цій статті розглядаються ключові аспекти інтеграції Celery з Django: від початкового налаштування до продакшн-конфігурації, маршрутизації завдань, моніторингу та типових питань на технічних співбесідах.
Celery 5.4+ повністю сумісний із Django 5.1 та Django 6.0. Усі приклади коду в цій статті використовують Redis як брокер повідомлень — найпоширеніший вибір для продакшн-середовищ.
Інтеграція Celery з Django: початкове налаштування
Першим кроком є створення файлу celery.py у кореневому пакеті проєкту. Цей модуль ініціалізує екземпляр Celery-додатку та налаштовує автоматичне виявлення завдань з усіх встановлених Django-додатків.
# myproject/celery.py
import os
from celery import Celery
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
app = Celery('myproject')
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks()Метод config_from_object із параметром namespace='CELERY' дозволяє зберігати всі налаштування Celery безпосередньо у settings.py з префіксом CELERY_. Це спрощує конфігурацію та зберігає єдину точку налаштувань проєкту.
Базова конфігурація брокера та бекенду результатів у settings.py виглядає наступним чином:
# myproject/settings.py
CELERY_BROKER_URL = 'redis://localhost:6379/0'
CELERY_RESULT_BACKEND = 'redis://localhost:6379/1'
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_TIMEZONE = 'UTC'Використання окремих баз Redis (0 і 1) для брокера та бекенду результатів є рекомендованою практикою. Це дозволяє ізолювати черги повідомлень від збережених результатів та спрощує моніторинг і масштабування кожного компонента окремо.
Створення та відправка завдань
Завдання у Celery — це звичайні Python-функції, декоровані @shared_task. Декоратор shared_task замість @app.task дозволяє визначати завдання без прямого імпорту екземпляра Celery-додатку, що робить код модулів повторно використовуваним.
Розглянемо типове завдання для відправки підтвердження замовлення з механізмом повторних спроб:
# orders/tasks.py
from celery import shared_task
from django.core.mail import send_mail
from orders.models import Order
@shared_task(bind=True, max_retries=3, default_retry_delay=60)
def send_order_confirmation(self, order_id: int) -> str:
"""Send confirmation email for a completed order."""
try:
order = Order.objects.select_related('user').get(id=order_id)
send_mail(
subject=f'Order #{order.id} Confirmed',
message=f'Your order totaling {order.total} has been confirmed.',
from_email='noreply@example.com',
recipient_list=[order.user.email],
)
return f'Email sent for order {order_id}'
except Order.DoesNotExist:
return f'Order {order_id} not found'
except Exception as exc:
# Retry on transient failures (SMTP timeout, etc.)
raise self.retry(exc=exc)Параметр bind=True надає доступ до об'єкта завдання через self, що дозволяє викликати self.retry(). Параметр max_retries=3 обмежує кількість повторних спроб, а default_retry_delay=60 встановлює затримку між спробами у 60 секунд. Варто звернути увагу, що при Order.DoesNotExist повторна спроба не виконується — немає сенсу повторювати запит, якщо замовлення не існує в базі даних.
Відправка завдання на виконання здійснюється через метод .delay():
# orders/views.py
from orders.tasks import send_order_confirmation
def complete_order(request, order_id):
# ... process payment, update order status ...
send_order_confirmation.delay(order_id)
return redirect('order_success', order_id=order_id)Виклик .delay(order_id) є скороченням для .apply_async(args=[order_id]). Завдання серіалізується, надсилається до брокера і виконується наступним доступним воркером. HTTP-відповідь повертається користувачу негайно, без очікування відправки електронного листа.
Маршрутизація завдань та управління чергами
У реальних проєктах різні типи завдань мають різні вимоги до ресурсів та часу виконання. Маршрутизація завдань по окремих чергах дозволяє ізолювати навантаження та призначати спеціалізовані воркери для кожного типу роботи.
# myproject/settings.py
CELERY_TASK_ROUTES = {
'orders.tasks.send_order_confirmation': {'queue': 'notifications'},
'reports.tasks.generate_monthly_report': {'queue': 'reports'},
'images.tasks.resize_upload': {'queue': 'media'},
}Кожна черга обслуговується окремим воркером з відповідними параметрами конкурентності:
# Start notification worker (fast tasks, high concurrency)
celery -A myproject worker -Q notifications -c 8 --loglevel=info
# Start report worker (slow tasks, limited concurrency)
celery -A myproject worker -Q reports -c 2 --loglevel=info
# Start media worker (CPU-bound, prefork pool)
celery -A myproject worker -Q media -c 4 -P prefork --loglevel=infoВоркер для сповіщень запускається з високою конкурентністю (-c 8), оскільки відправка електронних листів — це переважно I/O-операція. Воркер для звітів обмежений двома процесами, щоб не перевантажувати базу даних. Воркер для обробки медіафайлів використовує пул prefork, оптимальний для CPU-інтенсивних операцій масштабування зображень.
Celery Beat: періодичні завдання за розкладом
Celery Beat — це планувальник, який надсилає завдання до черги за визначеним розкладом. Він працює як окремий процес і підтримує як cron-подібні розклади, так і фіксовані інтервали.
# myproject/settings.py
from celery.schedules import crontab
CELERY_BEAT_SCHEDULE = {
'cleanup-expired-sessions': {
'task': 'accounts.tasks.cleanup_expired_sessions',
'schedule': crontab(hour=3, minute=0), # Daily at 3 AM UTC
},
'sync-inventory': {
'task': 'inventory.tasks.sync_external_inventory',
'schedule': 300.0, # Every 5 minutes
},
'generate-weekly-digest': {
'task': 'notifications.tasks.send_weekly_digest',
'schedule': crontab(hour=9, minute=0, day_of_week='monday'),
},
}Запуск планувальника здійснюється окремою командою:
celery -A myproject beat --loglevel=infoВажливо пам'ятати, що Celery Beat повинен запускатися як єдиний екземпляр. Запуск кількох процесів Beat призведе до дублювання завдань. У продакшн-середовищі рекомендується використовувати django-celery-beat для зберігання розкладу в базі даних, що дозволяє змінювати розклад без перезапуску процесу.
Моніторинг із Flower
Flower — це веб-інструмент реального часу для моніторингу Celery-кластера. Він надає інформацію про стан воркерів, активні та завершені завдання, статистику черг та графіки продуктивності.
# Install and run Flower
pip install flower
celery -A myproject flower --port=5555Після запуску Flower доступний за адресою http://localhost:5555. Серед ключових можливостей: перегляд стану кожного воркера, аналіз швидкості виконання завдань, відстеження помилок та виключень, а також можливість примусового завершення або перезапуску воркерів через веб-інтерфейс.
Для продакшн-середовища Flower слід захищати HTTP-автентифікацією або розміщувати за зворотним проксі з обмеженим доступом.
Django 6.0 та вбудована система завдань
Django 6.0, випущений у грудні 2025 року, представив нову вбудовану систему фонових завдань. Вона забезпечує базову функціональність для простих асинхронних операцій без необхідності встановлення зовнішніх залежностей.
Однак вбудована система Django має суттєві обмеження порівняно з Celery: відсутність маршрутизації завдань по чергах, обмежені можливості повторних спроб, відсутність вбудованого планувальника на рівні Celery Beat, а також менший контроль над конкурентністю та пулами воркерів.
Celery залишається оптимальним вибором для проєктів, які потребують складної маршрутизації, моніторингу через Flower, гнучкого планування періодичних завдань та масштабування окремих черг. Вбудована система Django 6.0 підходить для невеликих проєктів або прототипів, де простота важливіша за розширені можливості.
Продакшн-конфігурація та чеклист деплою
Перенесення Celery у продакшн-середовище вимагає ретельного налаштування параметрів надійності та продуктивності:
# myproject/settings.py — Production configuration
CELERY_TASK_ALWAYS_EAGER = False # Never True in production
CELERY_TASK_ACKS_LATE = True # Redelivery on worker crash
CELERY_WORKER_PREFETCH_MULTIPLIER = 1 # Fair scheduling
CELERY_TASK_REJECT_ON_WORKER_LOST = True # Reject on unexpected exit
CELERY_TASK_TIME_LIMIT = 300 # Hard kill after 5 minutes
CELERY_TASK_SOFT_TIME_LIMIT = 240 # SoftTimeLimitExceeded after 4 min
CELERY_WORKER_MAX_TASKS_PER_CHILD = 1000 # Prevent memory leaks
CELERY_BROKER_CONNECTION_RETRY_ON_STARTUP = TrueПараметр CELERY_TASK_ACKS_LATE = True гарантує, що повідомлення підтверджується лише після успішного виконання завдання. У разі аварійного завершення воркера завдання повертається у чергу. CELERY_TASK_TIME_LIMIT та CELERY_TASK_SOFT_TIME_LIMIT захищають від завислих завдань — спочатку генерується виключення SoftTimeLimitExceeded, а через хвилину процес примусово завершується.
Для управління Celery-воркерами на сервері рекомендується використовувати systemd:
# /etc/systemd/system/celery-worker.service
[Unit]
Description=Celery Worker
After=network.target redis.service
[Service]
Type=forking
User=django
Group=django
WorkingDirectory=/opt/myproject
ExecStart=/opt/myproject/venv/bin/celery -A myproject worker \
--loglevel=info --concurrency=4 --pidfile=/var/run/celery/worker.pid
ExecStop=/bin/kill -s TERM $MAINPID
Restart=always
[Install]
WantedBy=multi-user.targetКлючові елементи продакшн-чеклісту: Redis або RabbitMQ налаштований з persistence, Celery Beat запущений як єдиний екземпляр, Flower захищений автентифікацією, systemd-юніти створені для кожного воркера, налаштовані алерти на помилки завдань, логи централізовані та агрегуються.
Питання для технічних співбесід з Django та Celery
Нижче наведені типові питання, які ставлять на технічних співбесідах для middle та senior розробників.
Чим .delay() відрізняється від .apply_async()?
Метод .delay() є скороченим викликом .apply_async() і приймає лише позиційні та іменовані аргументи завдання. .apply_async() дозволяє додатково вказати чергу, затримку виконання (countdown), час запуску (eta), кастомний task_id та інші параметри маршрутизації.
Що відбувається із завданням, якщо воркер аварійно завершується?
Поведінка залежить від налаштування CELERY_TASK_ACKS_LATE. При значенні True повідомлення підтверджується лише після завершення завдання, тому при краші воркера воно повертається у чергу та виконується іншим воркером. При False (за замовчуванням) повідомлення підтверджується при отриманні, і завдання буде втрачено.
Як уникнути дублювання виконання завдання? Ідемпотентність завдань є ключовою. Можна використовувати унікальний ідентифікатор завдання, блокування через Redis (distributed lock) або перевірку стану в базі даних перед виконанням основної логіки.
Як обробляти ланцюжки залежних завдань?
Celery підтримує примітиви chain, group, chord та chunks. chain послідовно виконує завдання, передаючи результат наступному. group виконує завдання паралельно. chord — це group із callback-функцією, яка викликається після завершення всіх завдань групи.
Коли варто використовувати CELERY_TASK_ALWAYS_EAGER = True?
Виключно для локальної розробки та тестування. Цей параметр виконує завдання синхронно, без брокера, що спрощує дебагінг. У продакшні він повинен бути завжди False, інакше весь сенс асинхронної обробки втрачається.
Як моніторити стан Celery-кластера у продакшні?
Flower для реального часу, Prometheus + Grafana для метрик та алертів, Sentry для відстеження помилок. Celery експортує метрики через celery.events, які можна збирати кастомними consumers або через celery-exporter для Prometheus.
У чому різниця між prefork та eventlet пулами? Prefork створює окремі процеси і підходить для CPU-інтенсивних завдань. Eventlet (та gevent) використовує green threads і оптимальний для I/O-bound завдань із високою конкурентністю. Вибір залежить від характеру навантаження.
Готовий до співбесід з Django?
Практикуйся з нашими інтерактивними симуляторами, flashcards та технічними тестами.
Висновки
Celery залишається незамінним інструментом для Django-розробників у 2026 році, незважаючи на появу вбудованої системи завдань у Django 6.0. Правильне налаштування маршрутизації, механізмів повторних спроб та продакшн-конфігурації дозволяє будувати надійні розподілені системи. Для успішного проходження технічних співбесід важливо не лише знати API Celery, а й розуміти принципи роботи брокерів повідомлень, гарантії доставки та стратегії масштабування воркерів. Практичний досвід роботи з чергами, моніторингом та обробкою помилок значно підвищує шанси кандидата на отримання позиції.
Теги
Поділитися
Пов'язані статті

Django 5.2: Власна Middleware та Обробка Сигналів для Технічних Співбесід
Повний посібник з Django 5.2: побудова власної middleware, використання сигналів post_save та pre_save, асинхронна middleware, користувацькі сигнали та типові питання для технічних співбесід з прикладами коду.

Питання на співбесіді з Django та Python: Топ 25 у 2026 році
25 найпоширеніших питань на співбесіді з Django та Python. ORM, представлення, middleware, DRF, сигнали та оптимізація з детальними відповідями та прикладами коду.

Питання на співбесіді з Django: ORM, Middleware та DRF -- поглиблений розбір
Питання на співбесіді з Django: оптимізація ORM з select_related та prefetch_related, архітектура middleware, продуктивність серіалізаторів Django REST Framework, дозволи та пагінація.