在Django 中使用Celery

212 阅读5分钟

Celery 介绍

  • 一个简单、灵活且可靠、处理大量消息的分布是系统,可以在一台或者多台机器上运行。
  • 单个 Celery 进程每分钟可以处理数以百万计 的任务。
  • 通过消息进行通信,使用 消息队列(broker)客户端消费者 之间协调。

安装 Celery

pip install Celery

Celery 的使用

1. 创建 Celery 实例并加载配置

  1. 定义 Celery 包
    创建 Python package 的文件夹 celery_tasks

  1. 创建 Celery 实例
    celery_tasks 目录下创建 main.py
# celery 的入口
from celery import Celery

# 创建 celery 的实例
celery_app = Celery('demo')
  1. 加载 Celery 配置
    celery_tasks 目录下创建 config.py
# Celery 的配置文件

# 指定中间人、消息队列、任务队列、容器,使用 redis

# 指定消息队列的位置
broker_url = "redis://127.0.0.1/10"

2.定义任务

  1. 定义任务:celery_tasks.sms.tasks.py
# 定义任务
from ..main import celery_app


# 使用装饰器装饰异步任务,保证 celery 识别任务
@celery_app.task(name='send_sms_code')
def send_sms_code():
    # 任务内容
    pass
  1. 注册任务:celery_tasks.main.py
# celery 的入口
from celery import Celery

# 创建 celery 的实例
celery_app = Celery('demo')

# 加载配置
celery_app.config_from_object('celery_tasks.config')

# 自动注册注册任务
celery_app.autodiscover_tasks(['celery_tasks.sms'])

3. 启动 Celery 服务

celery -A celery_tasks.main worker -l info
  • -A 是指对应的应用程序,参数是项目中 Celery 实例的位置
  • worker 指这里要启动的 worker
  • -l 指日志的等级,比如 info 等级

celery worker 的工作模式

  • 默认是进程池方式,进程数以当前机器的 CPU 核数为参考,每个CPU 开四个进程。
  • 如何自己指定进程数:celery worker -A proj --concurrency=4
  • 如何改变进程池方式为协程方式:celery worker -A proj --concurrency=1000 -P eventlet -c 1000
# 安装 eventlet 模块
pip install eventlet

# 启用 Eventlet 池
celery -A celery_tasks.main worker -l info -P eventlet -c 1000

在django中使用

官方文档

配置方式

步骤:

  1. 项目 settings.py 同级目录下,创建 celery.py 来定义实例
  2. 项目 settings.py 同级目录下的 __init__.py 导入应用面程序
  3. settings.py 里面添加配置信息

第一步:celery.py

import os
from celery import Celery

# 设置celery命令行程序的环境变量
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'pldispatching.settings')

# app的实例
app = Celery('pldispatching')

# Django 设置模块添加为 Celery 的配置源。这意味着您不必使用多个配置文件,而是直接从 Django 设置中配置 Celery
# - namespace='CELERY' means all celery-related configuration keys
#   should have a `CELERY_` prefix.
app.config_from_object('django.conf:settings', namespace='CELERY')

# 可重用应用程序的一个常见做法是在单独的tasks.py模块中定义所有任务,Celery 确实有一种方法可以自动发现这些模块
app.autodiscover_tasks()

第二步:__init__.py

# 确保在 Django 启动时加载应用程序,以便@shared_task装饰器(稍后提到)将使用它
from .celery import app as celery_app

__all__ = ('celery_app',)

使用上面的代码,Celery 将自动从您安装的所有应用程序中发现任务,遵循tasks.py约定:

- app1/
    - tasks.py
    - models.py
- app2/
    - tasks.py
    - models.py

这样您就不必手动将各个模块添加到CELERY_IMPORTS设置中。

第三步:setttings.py 中添加配置  Celery 配置选项

# celery的配置
CELERY_BROKER_URL = 'redis://redis:6379/0'
CELERY_RESULT_BACKEND = 'redis://redis:6379/1'
CELERY_ACCEPT_CONTENT = ['application/json']
CELERY_RESULT_SERIALIZER = 'json'
CELERY_TASK_SERIALIZER = 'json'
CELERY_TIMEZONE = 'Asia/Shanghai'
CELERYD_MAX_TASKS_PER_CHILD = 10
CELERYD_LOG_FILE = os.path.join(BASE_DIR, "logs", "celery_work.log")
CELERYBEAT_LOG_FILE = os.path.join(BASE_DIR, "logs", "celery_beat.log")

使用 shared_task 装饰器

编写的任务可能会存在于可重用的应用程序中,而可重用的应用程序不能依赖于项目本身,因此您也不能直接导入您的应用程序实例。

装饰器允许您在@shared_task没有任何具体应用实例的情况下创建任务:

demoapp/tasks.py

# Create your tasks here
from demoapp.models import Widget
from celery import shared_task

@shared_task
def add(x, y):
    return x + y

@shared_task
def mul(x, y):
    return x * y

@shared_task
def xsum(numbers):
    return sum(numbers)

@shared_task
def count_widgets():
    return Widget.objects.count()

@shared_task
def rename_widget(widget_id, name):
    w = Widget.objects.get(id=widget_id)
    w.name = name
    w.save()

扩展

django-celery-results

使用 Django ORM/Cache 作为结果后端

使用步骤:

  1. 安装 django-celery-results 库
pip install django-celery-results
  1. 添加 django_celery_resultsINSTALLED_APPS 您的 Django 项目中 settings.py
INSTALLED_APPS = (
    ...,
    'django_celery_results',
)
  1. 通过执行数据库迁移来创建 Celery 数据库表:
python manage.py migrate django_celery_results
  1. 配置 Celery 以使用 django-celery-results 后端。
    使用 django settings.py 来配置 Celery ,添加一下设置
CELERY_RESULT_BACKEND = 'django-db'

对于缓存后端,您可以使用:
我们也可以使用 django 的 CACHES 设置中定义的缓存。
有关其他配置选项,请查看 任务结果后端设置参考。

django-celery-beat

具有管理界面的数据库支持的定期任务

有关详细信息,请参阅 使用自定义调度程序类

启动工作进程

在生产环境中,您将希望在后台将工作程序作为守护程序运行 - 请参阅守护程序-但对于测试和开发,能够使用 celery worker manage 命令启动工作程序实例很有用,就像您一样d 使用 Django 的 manage.py runserver

celery -A proj worker -l INFO

有关可用命令行选项的完整列表,请使用帮助命令:

celery help

监控管理 Flower

Flower 是 Celery 的基于 Web 的实时监控和管理工具。

官方文档:flower.readthedocs.io/en/latest/

使用

# 安装
pip install flower
# 运行命令
celery -A proj flower

默认端口是 http://localhost:5555 ,可以使用 -port 参数更改

celery -A proj flower --port = 5555

Broker URL 也可以通过 --broker 参数传递:

celery flower --borker=amqp://guest:guest@localhost:5672//
# 或者
celery flower --borker=redis://guest:guest@localhost:6379/0

--broker_api=http://guest:guest@rabbitmq:15672/api/

然后,可以通过 Web 浏览器中访问 Flower

http://localhost:55555