Асинхронные задачи в Django с использованием Celery и Redis: практическое руководство
Автор: Javohir Abdullayev · · Django

Введение: почему в проектах на Django необходима асинхронность?
В веб-приложениях пользовательский опыт (UX) и скорость отклика системы являются одними из ключевых факторов успеха. Представьте, что после регистрации пользователя ему отправляется письмо с подтверждением или генерируется объемный PDF-отчет. Если эти операции выполняются напрямую в цикле «запрос-ответ» (request-response) Django, пользователю придется ждать загрузки страницы в течение нескольких секунд.
Самый эффективный способ решить эту проблему — вынести тяжелые и ресурсоемкие процессы в фоновый режим (background tasks). В этом практическом руководстве мы с нуля научимся выполнять асинхронные задачи в приложении Django с помощью Celery и Redis.
Необходимые технологии и архитектура
В нашем проекте будут взаимодействовать три основных компонента:
- Django: основной веб-фреймворк и логика API.
- Redis: выступает в роли брокера сообщений (message broker), сохраняя задачи в очереди (queue).
- Celery: инструмент для приема и выполнения асинхронных задач в фоновом режиме (воркер / worker).
Шаг 1: Установка библиотек
Установите следующие пакеты в виртуальное окружение (venv) вашего проекта:
pip install django celery redisТакже на вашем компьютере или сервере должен быть установлен и запущен сервер Redis. Чтобы проверить это, введите в терминале следующую команду:
redis-cli ping
# Ответ: PONGШаг 2: Настройка Celery в проекте Django
Предположим, наш проект называется config. В основной директории проекта (там, где расположен settings.py) создайте файл celery.py:
import os
from celery import Celery
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
app = Celery('config')
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks()Затем экспортируем приложение Celery в файле __init__.py в той же директории:
from .celery import app as celery_app
__all__ = ('celery_app',)Шаг 3: Добавление настроек Redis в settings.py
Чтобы Celery знал, через какой брокер подключаться, добавьте следующие настройки в конец файла settings.py:
CELERY_BROKER_URL = 'redis://127.0.0.1:6379/0'
CELERY_RESULT_BACKEND = 'redis://127.0.0.1:6379/0'
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_TIMEZONE = 'Asia/Tashkent'Шаг 4: Создание асинхронной задачи (Task)
Теперь в вашем приложении (например, в приложении notifications) создайте файл tasks.py и напишите пример задачи:
from celery import shared_task
import time
@shared_task
def send_welcome_email(user_email):
# Имитация: отправка письма занимает 5 секунд
time.sleep(5)
print(f"Приветственное письмо отправлено на адрес {user_email}!")
return f"Письмо успешно отправлено: {user_email}"Шаг 5: Вызов задачи через View
Вместо прямого вызова функции мы отправляем ее в фоновый режим с помощью метода .delay():
from django.http import JsonResponse
from .tasks import send_welcome_email
def register_user_view(request):
user_email = request.GET.get('email', 'foydalanuvchi@pycoder.uz')
# Отправляем асинхронную задачу в очередь
send_welcome_email.delay(user_email)
return JsonResponse({
'status': 'success',
'message': 'Пользователь зарегистрирован, письмо отправляется в фоновом режиме!'
})Шаг 6: Запуск Celery Worker
Для полноценной работы системы понадобятся два отдельных окна терминала. В первом терминале запустите сервер Django:
python manage.py runserverВо втором терминале запустите процесс Celery worker:
celery -A config worker -l infoТеперь при отправке запроса на указанный URL-адрес представления пользователь мгновенно (за несколько миллисекунд) получит ответ, а 5-секундная ресурсоемкая операция будет автономно выполнена в окне Celery worker.
Заключение и лучшие практики
Связка Celery и Redis — один из самых надежных способов масштабирования проектов на Django и обеспечения устойчивости к высоким нагрузкам. В реальных проектах всегда обращайте внимание на следующее:
- Задачи должны быть идемпотентными (повторное выполнение не должно приводить к нежелательным побочным эффектам).
- Не передавайте крупные объекты (например, экземпляры моделей Django) в качестве аргументов задачи — передавайте только их идентификаторы (primary key).
- Для обработки ошибок используйте параметры
autoretry_for.
Теги: #Django #Celery #Redis #Backend #Python