Pull to refresh

Dramatiq как современная альтернатива Celery: больше нет проблем с версиями и поддержкой Windows

Reading time3 min
Views18K

Мы часто сталкиваемся с асинхронными задачами в веб-разработке. Когда нам нужны такие операции как:

  • Отправка электронных писем

  • Отправка запросов к внешним API

  • Долгие математические операции

  • Сложные запросы к базе данных

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

Celery и его проблемы

Самой популярной для языка программирования Python давно является Celery. Она предоставляет большие возможности работы с задачами, запуске их с определенным периодом и тонкой настройки.

До выхода Python 3.7 она была чуть ли не единственным способом реализовать асинхронную обработку задач. Но она, к сожалению, также известна своими проблемами с совместимостью с Python 3.7 и выше и отсутствием поддержки Windows с версии Celery 4.

И поэтому для тестирования своего приложения приходится разворачивать Сelery в Docker или переходить на Linux, что для многих является нежелательным.

Современное решение - Dramatiq

Поискав информацию я обнаружил прекрасную альтернативу Celery.

Dramatiq - это простая в использовании и надежная библиотека распределенной обработки задач для Python 3, написанная в 2017 году для решения проблем Celery.

If you’ve ever had to use Celery in anger, Dramatiq could be the tool for you.

Если вам когда-либо приходилось использовать Celery, испытывая гнев, то Dramatiq может быть инструментом для вас.

Так описывает Dramatiq автор библиотеки Богдан Поп. Какие же плюсы есть у Dramatiq?

  • Активно разрабатывается и используется в производстве

  • Отличная документация

  • Автоматическая перезагрузка кода ваших задач

  • Поддержка Redis и RabbitMQ

  • Понятный исходный код, который позволяет сообществу развивать библиотеку

И если вы ищете простую очередь выполнения задач, Dramatiq вам точно понравится. Ниже я приведу сравнительную таблицу актуальных решений в этой сфере:

 

Dramatiq

Celery

RQ

Поддержка Python 2

Нет

Да

Да

Поддержка Windows

Да

Нет

Нет

Простой исходный код

Да

Нет

Да

Отложенные задачи

Да

Да

Нет

Планирование задач

Нет

Да

Нет

Перезагрузка кода

Да

Нет

Нет

Поддержка RabitMQ

Да

Да

Нет

Поддержка Redis

Да

Да

Да

Пример асинхронной задачи с помощью Dramatiq

Хватит разговоров, давайте посмотрим на Dramatiq в действии!

Напишем простую функцию, получающую заголовки веб-страниц, и записывающую их в файл titles.txt. Для этого создадим файл titles_scraper.py и напишем в нем следующий код:

import requests
from bs4 import BeautifulSoup 


def get_page_title(url):   
    soup = BeautifulSoup(requests.get(url).text, "html.parser")   
    file = open("titles.txt", "a")   
    file.write("\n"+soup.title.text)

Пока что наша функция может быть вызвана только как get_page_title("example.com")и будет заставлять нас ждать, не давая выполнить более полезную работу, чем ожидание ответа с сервера. Давайте преобразуем нашу функцию и сделаем так, чтобы можно было запускать ее в отдельной очереди Dramatiq.

Для этого нам достаточно лишь добавить нужный декоратор нашей функции и выбрать, какой брокер мы будем использовать:

import requests
from bs4 import BeautifulSoup 
from dramatiq.brokers.redis import RedisBroker 
import dramatiq


# Я буду использовать Redis как брокера
dramatiq.set_broker(RedisBroker())

@dramatiq.actor
def get_page_title(url):   
    soup = BeautifulSoup(requests.get(url).text, "html.parser")   
	  file = open("titles.txt", "a")   
	  file.write("\n"+soup.title.text)

И это все, что надо сделать, чтобы объявить функцию Dramatiq. Вам не надо настраивать и долго конфигурировать Dramatiq для первого запуска, но при этом остается возможность настройки, когда это нужно.

Теперь запустим очередь задач:

dramatiq titles_scraper

Откроем консоль Python и попробуем выполнить нашу функцию:

>>> from titles_scraper import get_page_title
>>> get_page_title("https://google.com/") # Вам придется ждать около секунды
>>> get_page_title.send("https://google.com") # Код выполнится мгновенно, 
>>> # Dramatiq сам занялся выполнением кода

Теперь, открыв файл titles.txt, вы увидите заголовок страницы google.com.

Естественно, данный пример показывает лишь малую часть возможностей Dramatiq, которые помогут вам с асинхронными очередями задач. Цель данного примера была лишь в том, чтобы показать простоту Dramatiq.

Поддержка современными веб-фреймворками

Существуют также специализированные библиотеки для работы с Django и Flask:

Но если вы используете другой фреймворк, вам ничего не мешает разрабатывать с помощью чистого Dramatiq или даже написать свою библиотеку для работы с ним в вашем фреймворке.

Полезные ссылки

Tags:
Hubs:
Total votes 8: ↑7 and ↓1+12
Comments12

Articles