День 5: Створення масштабованої системи черги завдань за допомогою Django та Celery

pic

Зображення згенеровано за допомогою DALL.E

Веб-додатки часто мають завдання, які можуть зайняти значний час для виконання, наприклад, надсилання електронних листів, обробка великих наборів даних або взаємодія з зовнішніми API. Виконання цих завдань синхронно може сповільнити ваш додаток, що призведе до погіршення користувацького досвіду. Тут на допомогу приходить асинхронна обробка завдань з Django та Celery.

У цьому блозі ми:

  1. Налаштуємо Celery для асинхронної обробки завдань.
  2. Використаємо Redis як брокер повідомлень.
  3. Створимо та виконаємо фонові завдання.
    4.
    Моніторинг і керування завданнями з Flower.

До кінця цього процесу ви створите масштабовану систему черг завдань для розвантаження довготривалих завдань, що покращить відгук вашого додатку.

Крок 1: Налаштування Celery

1.1 Встановлення необхідних пакетів

Встановіть Celery і Redis:

pip install celery[redis]

Встановіть Flower для моніторингу завдань (необов'язково, але рекомендовано):

pip install flower

1.2 Налаштування Redis

Переконайтеся, що Redis встановлений та працює на вашій системі. Якщо ні, встановіть його:

  • Linux:
sudo apt update  
sudo apt install redis  
sudo systemctl start redis
  • macOS (за допомогою Homebrew):
brew install redis  
brew services start redis
  • Windows: Завантажте та встановіть Redis з redis.io.

1.3 Створення конфігурації Celery

1.
У кореневій директорії вашого проекту Django (поруч з settings.py) створіть файл з назвою celery.py:

from __future__ import absolute_import, unicode_literals  
import os  
from celery import Celery  

# Встановіть стандартний модуль налаштувань Django для програми 'celery'  
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'realtime_chat.settings')  

app = Celery('realtime_chat')  

# Використання рядка тут означає, що робітник не повинен серіалізувати  
# об'єкт конфігурації для дочірніх процесів.  
# Простір імен 'CELERY' означає, що всі конфігурації, пов'язані з Celery, повинні починатися з 'CELERY_'  
app.config_from_object('django.conf:settings', namespace='CELERY')  

# Автоматичне виявлення завдань у ваших додатках Django  
app.autodiscover_tasks()  

@app.task(bind=True)  
def debug_task(self):  
 print(f'Запит: {self.request!r}')

2.
Оновіть файл __init__.py вашого проекту для ініціалізації Celery:

from __future__ import absolute_import, unicode_literals  

# Це забезпечить, що додаток завжди імпортується, коли  
# Django запускається  
from .celery import app as celery_app  

__all__ = ('celery_app',)

1.4 Оновіть налаштування Django

Додайте наступні налаштування Celery до settings.py:

CELERY_BROKER_URL = 'redis://localhost:6379/0' # Redis як брокер  
CELERY_ACCEPT_CONTENT = ['json']  
CELERY_TASK_SERIALIZER = 'json'

Крок 2: Створення завдань

2.1 Визначте приклад завдання

У вашому додатку Django (наприклад, chat), створіть файл tasks.py:

# chat/tasks.py  

from celery import shared_task  
import time  

@shared_task  
def add(x, y):  
 time.sleep(5) # Симулюємо часомістке завдання  
 return x + y

2.2 Виклик завдання

Ви можете викликати завдання з будь-якого місця вашого проекту Django:

from chat.tasks import add  

# Запускаємо завдання асинхронно  
add.delay(10, 20)

Крок 3: Запуск Celery

1.
Запустіть робітника Celery:

celery -A realtime_chat worker --loglevel=info
  1. Перевірте завдання:
  • Запустіть завдання в оболонці Django:
python manage.py shell
from chat.tasks import add  
result = add.delay(10, 20)  
print(result.id) # ID завдання
  • Перевірте логи робітника, щоб побачити виконання завдання.

Крок 4: Моніторинг завдань за допомогою Flower

Flower — це інструмент для моніторингу Celery в реальному часі.

  1. Запустіть Flower:
celery -A realtime_chat flower

2.
Відкрийте панель керування Flower за адресою http://localhost:5555, щоб переглянути:

  • Активні завдання
  • Історія завдань
  • Статус робітників

Крок 5: Приклад: Відправка електронних листів

Створимо практичне завдання для асинхронної відправки електронних листів.

5.1 Встановлення бібліотек для електронної пошти

Якщо ще не встановлено, встановіть django-environ для роботи з змінними середовища:

pip install django-environ

Налаштуйте параметри електронної пошти в settings.py:

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'  
EMAIL_HOST = 'smtp.gmail.com'  
EMAIL_PORT = 587  
EMAIL_USE_TLS = True  
EMAIL_HOST_USER = os.getenv('EMAIL_HOST_USER') # Ваша електронна пошта  
EMAIL_HOST_PASSWORD = os.getenv('EMAIL_HOST_PASSWORD') # Ваш пароль від пошти

Встановіть змінні середовища в .env:

[email protected]  
EMAIL_HOST_PASSWORD=your_password

5.2 Створення завдання для відправки електронної пошти

Додайте завдання для відправки листів до tasks.py:

from celery import shared_task  
from django.core.mail import send_mail  

@shared_task  
def send_email(subject, message, recipient_list):  
 send_mail(  
 subject,  
 message,  
 '[email protected]',  
 recipient_list,  
 fail_silently=False,  
 )

5.3 Запуск завдання для відправки електронної пошти

Викликайте завдання у ваших в'юх або оболонці:

from chat.tasks import send_email  

send_email.delay(  
 'Welcome to MyApp',  
 'Thank you for signing up!',  
 ['[email protected]']  
)

Крок 6: Обробка помилок та повторні спроби

6.1 Повтор спроби у разі невдачі

Використовуйте метод retry, щоб повторювати завдання при невдачі:

from celery import shared_task  
from celery.exceptions import MaxRetriesExceededError  

@shared_task(bind=True, max_retries=3)  
def unreliable_task(self):  
 try:  
 # Імітація завдання, що іноді завершується з помилкою  
 result = 1 / 0  
 except Exception as exc:  
 raise self.retry(exc=exc, countdown=10)

Крок 7: Розгортання Celery в продакшн

7.1 Використання процес-менеджера

Використовуйте процес-менеджер, такий як systemd або supervisor, для запуску робітників Celery у продакшн-середовищі.
Наприклад, файл сервісу для systemd:

[Unit]  
Description=Celery Worker  
After=network.target  

[Service]  
Type=forking  
User=your_user  
WorkingDirectory=/path/to/your/project  
ExecStart=/path/to/venv/bin/celery -A realtime_chat worker --loglevel=info  
Restart=always  

[Install]  
WantedBy=multi-user.target

7.2 Масштабування робітників

Масштабуйте робітників Celery, збільшуючи кількість одночасних завдань:

celery -A realtime_chat worker --loglevel=info --concurrency=4

У цьому блозі ви дізналися, як інтегрувати Celery у ваш Django-додаток для асинхронної обробки завдань. Використовуючи Redis як брокера повідомлень, ви створили масштабовану систему черги завдань для ефективної обробки довготривалих завдань.
Ви також дізналися, як моніторити завдання за допомогою Flower та реалізувати повтори для обробки помилок.

pic

Зображення, створене за допомогою DALL.E

Що далі?

У День 6 ми дослідимо можливості адміністративного інтерфейсу Django. Ви дізнаєтесь, як:

  • Налаштувати перегляд адміністратора.
  • Додавати розширені фільтри та дії.
  • Створювати персоналізовані панелі адміністратора.

Залишайтеся з нами для цієї захоплюючої подорожі в налаштування адміністративної частини Django!

Якщо цей блог був корисним для вас:

  • Слідкуйте за мною на Medium, щоб не пропустити наступний пост у цій серії та інші поради з Django.
  • Поділіться своїми думками чи питаннями в коментарях — буду радий почути від вас!
  • Не забудьте поставити лайк та поділитися цим постом із вашою мережею — це допомагає більше розробникам дізнатися про Django.

Продовжуємо будувати та масштабувати разом! 🚀

Перекладено з: Day 5: Building a Scalable Task Queue System with Django and Celery

Leave a Reply

Your email address will not be published. Required fields are marked *