24 июля 2019 г. 21:48

300

Асинхронные задачи на Django с использованием Celery + Redis

Допустим вы реализуете загрузку на видео с последующей конвертацией. Или регистрируете пользователя на вашем сайте , а после этого отправляете письмо и создаете преьюшку для его фотографии. Если это реализовать с помощью http-запросов , то мы заставим пользователя ждать ответа , пока этот функционал не выполнится.А пользователи не любят ждать. Это вам не await , а живые люди.И чтобы они не ждали , мы можем добавить эти задачи в очередь и они будут выполняться асинхронно и пользователи могут совершать другие действия на нашем сайте. Кроме этого у нас могут и другие задачи , которые нужно выполнять в определенное время и в фоновом режиме. И для решения таких задач для Django используется Celery. Также неплохой альтернативой является RQ

В этой статье будет мало теории.

Так почему Redis , а не RabbitMQ или база данных (PostgresSql, Mysql) ?

Если вам нужно гарантированное выполнение задач(Тасков), то обычно выбирают RabbitMQ.

Базы данных в качестве бекенда не советуют использовать , так как они не предназначены для этого. В этой статье автор на своем опыте показывает , почему их не следует использовать и приводит доводы к этому.

А вот Redis - это хранилище , где данные хранятся в оперативной памяти и их быстро можно получить.

И вообще , Redis легок в установке и понятнее в использовании чем RabbitMQ.

Так как в качестве бэкенда мы будем выбрали Redis и поэтому мы установим celery в наше виртуальное окружение следующим образом.


pip install celery [redis]

Дальше нам нужно создать celery.py

Во всех статьях про celery в качестве примеров приводятся задачи, которые создают пользователей или задачи, которые отправляют письма пользователям(что совсем логично и правильно) или задачи, где просто тупо складываются два числа.

Я решил пробить дно и в качестве примера создам задачу , которая будет ждать 10 секунд и завершится.

Создадим файл tasks.py

Перед тем как мы будем использовать нашу задачу в нашем примере мы запустим celery в отдельном окне

Если у вас Windows, то официально celery четвертой версии официально не поддерживается , но есть решения, которые позволяют запустить celery. Вот тут

Потом эту задачу, мы можем использовать в своей вьюхе следующим образом

Многие начинающие программисты попадаются на эту удочку и думают , что это задача будет выполняться асинхронно в фоновом режиме , но пользователь будет ждать ответа 10 секунд , пока не выполнится эта задача.

Декоратор @app.task нашу функцию превращает в задачу(task), которая помещается в очередь и она не будет выполняться асинхронно

Чтобы это задача выполнялась асинхронно , то мы должны вместо


endure_ten_seconds()

Написать


endure_ten_seconds.delay()

После вызова задачи с помощью delay мы отправляем задачу в очередь и не ждем завершения результата. А вот в первом случаем мы ждали бы 10 секунд, чтобы дождаться результата.

Заключение

Основной целью данной статьи была возможность добавления Celry в наш Джанго проект и мы не вдавались в теорию и остальную лирику. Это отправная точка. В следующих статьях про Celery я напишу как можно запускать периодические задачи, как запустить задачу в определенное время(например через 20 минут) и другие полезные вещи.

Смело можете задавать любые вопросы по теме и высказывать свою критику

comments powered by Disqus