Celery的使用(django项目实例)

Celery的使用(django项目实例)

  • Celery的介绍
    • Celery的核心模块
    • Celery优点和流程
    • 安装Celery
  • 简单的使用celery
  • django项目中使用celery
    • 创建模块任务
      • 发送验证邮件实例
      • 发送短信验证码实例
  • flower模块
  • celery定时任务(计划任务)
    • 启动定时任务:

前文:Celery中文文档:http://docs.jinkan.org/docs/celery/getting-started/first-steps-with-celery.html#first-steps
版本容易踩坑,本文版本为:

  • celery 3.1.26.post2
  • django-celery 3.3.0
  • django-redis 4.10.0
  • redis 2.10.6

Celery的介绍

Celery 是一个 基于python开发的分布式异步消息任务队列,通过它可以轻松的实现任务的异步处理, 如果你的业务场景中需要用到异步任务,就可以考虑使用celery, 举几个实例场景中可用的例子:

  • 你想对100台机器执行一条批量命令,可能会花很长时间 ,但你不想让你的程序等着结果返回,而是给你返回一个任务ID,你过一段时间只需要拿着这个任务id就可以拿到任务执行结果, 在任务执行ing进行时,你可以继续做其它的事情。
  • 你想做一个定时任务,比如每天检测一下你们所有客户的资料,如果发现今天 是客户的生日,就给他发个短信祝福

Celery 在执行任务时需要通过一个消息中间件来接收和发送任务消息,以及存储任务结果, 一般使用rabbitMQ or Redis,后面会讲

Celery的核心模块

Celery有一下5个核心角色
Task
就是任务,有异步任务和定时任务
Broker
中间人,接收生产者发来的消息即Task,将任务存入队列。任务的消费者是Worker。Celery本身不提供队列服务,推荐用Redis或RabbitMQ实现队列服务。
Worker
执行任务的单元,它实时监控消息队列,如果有任务就获取任务并执行它。
Beat
定时任务调度器,根据配置定时将任务发送给Broler。
Backend
用于存储任务的执行结果。
各个角色间的关系看下面这张图理解一下:

Celery优点和流程

Celery有以下优点:

  • 简单:一单熟悉了celery的工作流程后,配置和使用还是比较简单的
  • 高可用:当任务执行失败或执行过程中发生连接中断,celery 会自动尝试重新执行任务
  • 快速:一个单进程的celery每分钟可处理上百万个任务
  • 灵活: 几乎celery的各个组件都可以被扩展及自定制

Celery基本工作流程图:
Celery的使用(django项目实例)_第1张图片

安装Celery

同时需要安装中间人broker,通常是RabbitMQ或者Redis,自行百度安装
这是redis和celery同时安装:

pip install -U "celery[redis]"

安装RabbitMQ:

sudo apt-get install rabbitmq-server

简单的使用celery

from celery import Celery
# broker是指定中间存储,backend是结果存储
app = Celery('tasks',
             broker='redis://127.0.0.1/3',
             backend='redis://127.0.0.1/3')

# app = Celery('tasks',broker='amqp://192.168.3.108',backend='rpc://192.168.3.108',  # 新版本rpc将初步替代amqp,用的还是RabbitMQ# backend='amqp://192.168.3.108',  # 如果是旧版本,没有rpc,那只能用amqp)

# 创建任务函数
@app.task
def work1():
    print('这是任务1')
    
# 任务的发布,delay这里填函数参数
work1.delay()

启动celery,在终端启动
celery -A 任务模块名 worker -l info

django项目中使用celery

在项目文件夹下创建一个python package文件夹,取名为celery_tasks,里面分别创建启动文件main.py,配置文件config.py
config.py内容,需要大写,这里的redis库不要用已经配置过的:

# 这是配置celery文件
BROKER_URL= 'redis:/127.0.0.1/0'

main文件内容

# 启动文件
from celery import Celery

# 告知celery用django的配置文件进行配置
import os
if not os.getenv('DJANGO_SETTINGS_MODULE'):
    os.environ['DJANGO_SETTINGS_MODULE']= 'shanghuishop.settings.dev'

# 创建应用
app = Celery('shanghui')

# 导入celery的配置文件
# app.config_from_object('celery_tasks.config')

# 任务
app.autodiscover_tasks(['celery_tasks.email', 'celery_tasks.message'])

# celery -A celery_tasks.main worker -l info

创建模块任务

在之前celery_tasks文件夹中创建新的文件夹email和message分别用来处理发送验证邮件和短信

发送验证邮件实例

这里先写发送验证email的任务,创建一个tasks.py文件在email文件夹下:

from django.core.mail import send_mail
# 在当前的tasks里面书写邮件发送任务

from celery_tasks.main import app


@app.task
def my_send(url, from_email, rec_list,html_msg):
	# 传入四个参数分别是链接,发件人,收件人列表,html信息
    send_mail('用户邮件激活', '点击链接激活邮箱:' + url, from_email, rec_list, html_message='点击这个激活:'+html_msg)

去对应的序列化器修改:

from celery_tasks.email.tasks import my_send
	# 发送即可
	my_send.delay(url, from_email, rec_list, html_msg)

发送短信验证码实例

还是创建一个tasks文件到message文件夹下:

from celery_tasks.main import app
from shanghuishop.libs.CCPRestSDK.sms import CCP

# 发送短信验证码
@app.task(name='send_msg')
def send_msg(msg_list):
    ccp = CCP()
    res = ccp.send_template_sms(
        '18814886773', msg_list, 1)
    print('celery短信发送结果', res)

然后是对应的views文件修改原来的功能:

from celery_tasks.message.tasks import send_msg
# 发送的具体内容,详情看之前blog
msg_list = [msg, constants.PHONE_CODE_REDIS_EXPIRES // 60]
# 发送的功能
send_msg.delay(msg_list)

flower模块

flower 是一个 celery 的监控工具,它提供了一个图形用户界面,可以极大的方便我们监控任务的执行过程, 执行细节及历史记录,还提供了统计功能。
flower 安装

pip install flower

flower 使用简介,首先启动通过命令行启动 flower 进程:

flower -A proj --port=5555

celery定时任务(计划任务)

还是在django项目中使用,配置内容都在config里写,注意celery版本不同需要大小写要求不同,3.1版本要大写:

# 这是配置celery文件
from datetime import timedelta
from celery.schedules import crontab

# 指定任务队列的位置
BROKER_URL = "redis://127.0.0.1/3"
# 指定消息执行结果的位置
CELERY_RESULT_BACKEND = "redis://127.0.0.1/3"
# 一定要写下面这句,指定时区,否则celery默认使用utc时间,设置的hour会延迟8小时执行
CELERY_TIMEZONE = 'Asia/Shanghai'

# 这里是四个最典型的定时任务,更多用法自行百度crontab语法
CELERYBEAT_SCHEDULE = {
    # 定时任务一: 每5分钟执行一次任务(refresh1)
    'refresh1': {
        "task": "celery_tasks.email.tasks.refresh",
        "schedule": crontab(hour='*/5'),
        "args": (), # 填参数
    },
    # 定时任务二: 每天的凌晨2:00,执行任务(refresh2)
    'refresh2': {
        "task": "celery_tasks.email.tasks.refresh",
        'schedule': crontab(minute=0, hour=2),
        "args": ()
    },
    # 定时任务三:每个月的1号的6:00启动,执行任务(refresh3)
    'refresh3': {
        "task": "celery_tasks.email.tasks.refresh",
        'schedule': crontab(hour=6, minute=0, day_of_month='1'),
        "args": ()
    },
    # 每隔20秒启动
    'sendemail every 20 seconds': {
        'task': 'celery_tasks.email.tasks.send',
        'schedule': timedelta(seconds=20),
        'args': ()
    }
}

email.tasks.py内容为:

from django.core.mail import send_mail
from django.conf import settings
# 在当前的tasks里面书写邮件发送任务

from celery_tasks.main import app


@app.task(name='my_send')
def my_send(url, from_email, rec_list, html_msg):
    # 传入四个参数分别是链接,发件人,收件人列表,html信息
    send_mail('用户邮件激活', '点击链接激活邮箱:' + url, from_email, rec_list, html_message='点击这个激活:'+html_msg)


@app.task()
def send():
    send_mail('用户邮件激活', '点击链接激活邮箱:' + 'http://www.baidu.com',settings.DEFAULT_FROM_EMAIL, ['[email protected]', ])


@app.task()
def refresh():
    print('refresh函数')
    

启动定时任务:

注意要在项目根目录下开启两个终端,按顺序执行,beat是定时任务启动

celery -A celery_tasks.main worker -l info
celery -A celery_tasks.main beat -l info

项目目录图:
Celery的使用(django项目实例)_第2张图片

你可能感兴趣的:(Django)