Django и Celery. №1. Установка
Вступление
В этом руководстве по Django Celery я расскажу о
- Как настроить Celery с Django
- Как протестировать задачу Celery в оболочке Django
- Как контролировать Celery с помощью Flower
Вы можете получить исходный код этого проекта в конце этого руководства.
Зачем проекту Django нужен Celery
Celery может помочь запускать задачи рабочем процессе вместо web-процесса, поэтому в web-процессе мы можем немедленно вернуть HTTP-ответ (даже если задача worker process все еще выполняется) нашему пользователю, цикл запроса не будет заблокирован, и пользовательский интерфейс будет отзывчивым.
Ниже приведены некоторые примеры использования Celery.
-
Вы создали приложение для комментариев, которое поддерживает операции упоминания, пользователь может использовать "@" чтобы упомянуть другого пользователя, и они будут получать уведомления по электронной почте. Если один пользователь упоминает 10 человек в одном комментарии, веб-процессу необходимо обработать и отправить 10 электронных писем. Иногда это может занять много времени (сеть, сервер и другие факторы), но Celery может позволить вам отправлять электронные письма в фоновом процессе, и вы можете вернуть HTTP-ответ пользователю, чтобы ему не нужно было ждать.
-
Когда пользователь загружает изображение в ваше веб-приложение, вам необходимо создать миниатюру, вы можете выполнить задачу в рабочем процессе
-
Вам нужно выполнить некоторую периодическую работу, например, создать ежедневный отчет, очистить данные просроченной сессии. Вы можете позволить Celery помочь отправить задачу в заданное время в worker process.
Когда вы создаете веб-приложение, вы должны попытаться сделать время отклика вашего веб-приложения ниже 500 мс, если некоторое время отклика велико, вы должны выяснить причину и попытаться ее решить. В решении этой проблемы может помочь Celery.
Celery VS RQ
RQ (Redis Queue) - еще одна библиотека Python, которая может помочь вам решить вышеуказанные проблемы.
Основная логика RQ (Redis Queue) и Celery одинакова (Producer/Consumer Pattern), здесь я бы сравнил их и дал вам лучшее понимание.
-
RQ (Redis Queue) прост в освоении, и его цель - снизить барьер для использования async worker. В нем отсутствуют некоторые функции, и его можно использовать только с Redis и Python.
-
Celery предоставляет нам больше функций, поддерживает множество различных серверных программ и более гибкий, поэтому документ немного сложен, и новичок может быть немного запутан.
Поскольку Celery может помочь мне лучше решить некоторые проблемы, я предпочитаю Celery, и я написал эту статью, чтобы помочь читателю (особенно новичку) быстро изучить Celery!
Брокер сообщений и бэкэнд результатов
Брокер сообщений - это хранилище, которое взаимодействует как транспорт между производителем и потребителем.
Из документа Celery рекомендуется брокер сообщений (message broker) RabbitMQ, потому что он поддерживает AMQP (Расширенный протокол очереди сообщений)
Но во многих случаях нам не нужно использовать функции AMQP и другие message broker, такие как Redis, тоже нормально.
Бэкэнд результатов - это хранилище, в котором сохраняется информация о результатах и ошибках или задача Celery.
Redis здесь рекомендуется.
Как настроить Celery
Далее я покажу вам, как импортировать Celery worker в ваш проект Django.
Мы будем использовать Redis в качестве брокера сообщений и бэкэнда результатов, поэтому его будет немного проще настроить. Но вы можете выбрать предпочитаемого брокера сообщений и бэкэнд результатов в зависимости от ваших требований.
Используйте Docker, чтобы подготовить среду разработки
Если вы работаете на Linux или Mac, вы можете использовать диспетчер пакетов, чтобы настроить Redis за вас. (brew, apt-get install), однако я хотел бы порекомендовать вам попробовать Docker, чтобы установить сервер Redis.
-
Вы можете скачать docker client здесь Get Docker
-
Затем попробуйте запустить службу Redis
$ docker run -p 6379:6379 --name some-redis -d redis
Команда выше запустит redis службу на127.0.0.1:6379
-
Если вы хотите использовать здесь RabbitMQ в качестве брокера сообщений, вам просто нужно изменить приведенную выше команду, чтобы она работала.
-
Закончив работу, вы можете закрыть контейнер Docker, и окружение вашего хост-компьютера по-прежнему будет чистым.
Затем давайте импортируем Celery в наш проект Django.
Создать проект django
# создайте новый python virtualenv и активируйте $ pip install django == 2 .2 $ django-admin startproject django_celery_example $ python manage.py startapp опросы
Ниже представлена структура проекта
. ├── django_celery_example │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py └── опросы ├── __init__.py ├── admin.py ├── apps.py ├── миграции │ └── __init__.py ├── models.py ├── tests.py └── views.py
celery.py
Далее приступим к установке и настройке Celery.
# это установит Celery и redis-py $ pip install -r requirements.txt
Создайте django_celery_example/celery.py
рядом с django_celery_example/wsgi.py
""" Celery config file https://docs.celeryproject.org/en/stable/django/first-steps-with-django.html """ from __future__ import absolute_import import os from celery import Celery # this code copied from manage.py # set the default Django settings module for the 'celery' app. os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django_celery_example.settings') # you change change the name here app = Celery("django_celery_example") # read config from Django settings, the CELERY namespace would make celery # config keys has `CELERY` prefix app.config_from_object('django.conf:settings', namespace='CELERY') # load tasks.py in django apps app.autodiscover_tasks(lambda: settings.INSTALLED_APPS) @app.task def add(x, y): return x / y
init .py
Продолжаем изменять django_celery_example/__init__.py
from __future__ import absolute_import, unicode_literals # This will make sure the app is always imported when # Django starts so that shared_task will use this app. from .celery import app as celery_app __all__ = ('celery_app',)
settings.py
Поскольку Celery может читать конфигурацию из файла настроек Django, мы можем добавить туда конфигурацию для лучшего управления.
CELERY_BROKER_URL = "redis://127.0.0.1:6379/0" CELERY_RESULT_BACKEND = "redis://127.0.0.1:6379/0"
Есть кое-что, о чем следует помнить.
Когда вы проверяете документ Celery, вы увидите, что broker_url
- это ключ конфигурации, который вы должны установить для брокера сообщений, в приведенном выше celery.py
-
app.config_from_object('django.conf:settings', namespace='CELERY')
скажите Celery, чтобы он считывал значение изCELERY
пространства имен, поэтому, если вы установите егоbroker_url
в файле настроек Django, этот параметр не будет работать. Это правило также применяется для всех ключей конфигурации Celery в документе. -
Некоторые ключи конфигурации различаются между Celery 3 и Celery 4, поэтому, пожалуйста, проверьте документацию при выполнении конфигурации.
Отправить работу в Celery
Теперь настройка конфигурации завершена, давайте начнем пробовать Celery и посмотрим, как это работает. Здесь мы будем запускать некоторые команды в другом терминале, но я рекомендую вам взглянуть на Tmux когда у вас будет время.
Сначала запустите Celery worker в одном терминале, django_celery_example - это имя приложения Celery, которое вы установили в django_celery_example/celery.py
$ celery worker -A django_celery_example --loglevel=info [config] .> app: django_celery_example:0x1034783c8 .> transport: redis://127.0.0.1:6379/0 .> results: redis://127.0.0.1:6379/0 .> concurrency: 8 (prefork) .> task events: OFF (enable -E to monitor tasks in this worker) [queues] .> celery exchange=celery(direct) key=celery [tasks] . django_celery_example.celery.add
Во-вторых, давайте запустим веб-приложение, которое поможет нам отслеживать задачу Celery (чуть позже я расскажу об этом подробнее).
$ flower -A django_celery_example --port=5555
Затем вы можете открыть, http://localhost:5555/ и вы увидите веб-панель, которая поможет вам проверить детали воркера Celery.
Далее входим Django shell и пытаемся отправить какие-то задачи Celery
$ python manage.py migrate $ python manage.py shell
>>> from django_celery_example.celery import add >>> task = add.delay(1, 2)
Ниже приведены некоторые моменты
-
Мы используем xxx.delay для отправки сообщения брокеру сообщений, и рабочий процесс выбирает эту задачу и запускается.
-
После того, как вы нажмете enter после ввода
task = add.delay(1, 2)
, код скоро завершится (не заблокирован), ноadd
метод все еще работает в рабочем процессе celery. -
Если вы проверите вывод терминала celery, вы увидите что-то вроде этого
03:54:40,072: INFO/MainProcess] Received task: django_celery_example.celery.add[6501dc00-d422-4832-b8ab-fc72a8311586] 03:54:50,082: INFO/ForkPoolWorker-8] Task django_celery_example.celery.add[6501dc00-d422-4832-b8ab-fc72a8311586] succeeded in 10.00722316399333s: 0.5
Рабочий процесс получил задачу в 03:54:40, и через 10 секунд задача была выполнена успешно.
Думаю, теперь у вас уже есть базовое представление о рабочем процессе. Попробуем еще один блок кода
>>> import time >>> from django_celery_example.celery import add >>> task = add.delay(1, 2) >>> >>> for i in range(13): >>> time.sleep(1) >>> print(task.state, task.result) PENDING None PENDING None PENDING None PENDING None PENDING None PENDING None PENDING None PENDING None PENDING None SUCCESS 0.5 SUCCESS 0.5 SUCCESS 0.5 SUCCESS 0.5
-
Когда мы вызываем
delay
метод, мы получаемtask
экземпляр, который мы можем использовать для запроса состояния и результата задачи. -
Здесь мы
poll
состояние и результат каждые 0,5 секунды, и вы можете видеть прогресс.
Затем давайте попробуем вызвать ошибку в работнике Celery и посмотрим, что произойдет.
>>> import time >>> from django_celery_example.celery import add >>> task = add.delay(1, 0) >>> type(task) celery.result.AsyncResult # here we wait for about 10 seconds, and then check the state and result >>> task.state 'FAILURE' >>> task.result ZeroDivisionError('division by zero')
Как видите, после вызова метода задержки мы получаем AsyncResul
tэкземпляр.
Мы можем использовать его для многих полезных вещей, таких как
-
Проверить состояние задачи.
-
Проверьте возвращаемое значение задачи или сведения об исключении.
-
Проверьте другие метаданные задачи.
Мониторинг Celery с помощью Flower
flower
может позволить нам отслеживать Celery на удобной для пользовательского интерфейса веб-странице, потому что это может помочь нам лучше понять более подробную информацию о Celery, поэтому я решил поговорить об этом, прежде чем углубляться в дальнейшие исследования.
URL-адрес веб-панели управления: http://127.0.0.1:5555/
Пожалуйста, проверьте tasks
страницу.
Вы должны обратить внимание на UUID
столбец, который AsyncResult.id
Вы также можете получить аналогичные сведения об одной задаче с помощью кода ниже.
>>> from celery.result import AsyncResult >>> # 10da60be-80f6-437f-af68-c339ac6ebd7c here is the UUID copied from web page >>> task = AsyncResult('10da60be-80f6-437f-af68-c339ac6ebd7c') >>> task.state 'FAILURE' >>> task.result ZeroDivisionError('division by zero')
Когда вы изучаете Celery, вы можете использовать Flower для понимания деталей.
При развертывании проекта на сервере Flower необязателен. Я имею в виду, что вы также можете использовать команды Celery, чтобы управлять приложением и проверять статус.
Заключение
В этом сообщении в блоге я рассказал о некоторых основных частях Celery. Желаю, чтобы вы уже хорошо понимали весь рабочий процесс.
https://www.accordbox.com/blog/how-to-setup-celery-django/
Вернуться на верх