celery

本文介绍了Celery异步任务队列系统,它适用于异步处理耗时操作,可提高用户体验。阐述了其特点,包括简单、高效、灵活,分析了架构原理,涵盖消息队列、任务执行单元和结果存储。还说明了应用场景、下载安装和使用方法,以及与Django结合使用的步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.什么是celery

Celery是一个功能完备即插即用的异步任务队列系统.它适用于异步处理问题,当发送邮件,会上传文件,图像处理等一些比较耗时的操作,我们可以将其异步执行,这样用户不需要等很久,提高用户体验.
专注于实时处理异步任务队列同时也支持任务调度.

官方文档:http://docs.jinkan.org/docs/celery/getting-started/index.html

2.特点

(1)简单,易于维护,有丰富的文档
(2)高效,单个celery进程每分钟可以处理数百万个任务
(3)灵活,celery中几乎每个部分都可以自定义扩展

3.celery架构原理

Celery的架构由三部分组成,消息队列(message broker),任务执行单元(worker)和任务执行结果存储(task result store)组成。
一个celery系统可以包含很多的broker和worker;

消息队列

Celery本身不提供消息服务,但可以方便的和第三方提供的中间件继承,如:redis,Rabbit,MongoDB等;

任务执行单元

Worker 是Celery的任务处理者,持续运行对消息队列中的任务不断轮询,读取任务
注意:任务执行中,支持任务错误处理机制,错误任务是放到任务队列中还是结果队列中要看该任务有没有重新执行的必要,默认是放在结果队列中的,也就是结果队列中存放着错误信息记录.

任务执行结果储存

task result store是将任务处理的结果进行存储在redis等数据库,

4.应用场景

(1)异步任务:耗时的任务交给Celery去处理,如发送短信/邮件,消息推送
(2)定时任务:如订单的定时关闭,定时统计等;

5.下载安装

pip install -U celery      #-U是update的意思,有就进行更新,没有就安装
#后面单独将celery运行起来就可以了

6.使用

6.1执行异步任务

目录结构:
在这里插入图片描述
在注册程序main.py中创建Celery对象实例,Celery实例是我们使用celery所有功能的入口,比如创建任务管理任务.
main.py

# 主程序
from celery import Celery
# 创建celery实例对象
app = Celery("luffy")

# 通过app对象加载配置,文件路径
app.config_from_object("mycelery.config")

# 自动搜索并加载任务
# 参数必须必须是一个列表,里面的每一个任务都是任务的路径名称
# app.autodiscover_tasks(["任务1","任务2"])
app.autodiscover_tasks(["mycelery.sms","mycelery.cache"]) #会自动识别sms目录下面的tasks.py文件中的任务,所以不需写成mycelery.sms.tasks

# 启动Celery的命令
# 强烈建议切换目录到项目的根目录下启动celery!!
# celery -A mycelery.main worker --loglevel=info

配置文件config.py,代码

# 任务队列的链接地址(变量名必须叫这个)
broker_url = 'redis://127.0.0.1:6379/14'  
# 结果队列的链接地址(变量名必须叫这个)
result_backend = 'redis://127.0.0.1:6379/15'

创建一个任务文件sms/tasks.py

# celery的任务必须写在tasks.py的文件中,别的文件名称不识别!!!
from mycelery.main import app

@app.task(name="send_sms")  # name表示设置任务的名称,如果不填写,则默认使用函数名(路径)做为任务名
def send_sms():
    print("发送短信!!!")

@app.task  # name表示设置任务的名称,如果不填写,则默认使用函数名做为任务名
def send_sms2():
    print("发送短信任务2!!!")

接下来,我们运行celery,在终端,项目根目录下(也就是mycelery的外层目录里面)执行指令

celery -A mycelery.main worker --loglevel=info (或者直接写info也行) #-A是指定celery启动入口

效果如下:
在这里插入图片描述
运行起来后,如果有添加了新的任务,需要重新启动celery.
测试:
在mycelery文件夹下创建一个python文件进行测试

#引入任务
from mycelery.sms.tasks import send_sms  
#执行任务
send_sms.delay() #这就是将任务交给worker去执行了,这个任务在上面的时候已经加到队列中了,所以调用它的意思就是让worker去队列中找到send_sms这个任务去执行
#然后运行我们这个文件,右键运行就行,celery会在后台一直运行着

在redis中可以查看任务执行结果
如果想获取任务结果可以通过get方法,或者AsyncResult这个类来拿

方式1import time
from mycelery.sms.tasks import send_sms
from mycelery.mail.tasks import send_email

ret = send_sms.delay()
print(ret,type(ret))
print(ret.ready())
print(ret.id)
# time.sleep(3)
print(ret.ready())
print(ret.get(timeout=1),)

方式2
import time
from mycelery.sms.tasks import send_sms
from mycelery.mail.tasks import send_email

from celery.result import AsyncResult
ret = send_sms.delay()  #执行的任务如果需要参数,那么就直接在delay方法里面写:send_sms(mobile,sms_code),执行时:delay(mobile,sms_code)
async_task = AsyncResult(id=ret.id,app=send_sms)

print(async_task.successful())
result = async_task.get()
print(result)

celery与django结合使用:
在main.py主程序中对django的配置文件进行加载

# 主程序
import os
from celery import Celery
# 创建celery实例对象
app = Celery("luffy") #celery对象可以创建多个,所以我们最好给我们当前的celery应用起个名字,比如叫做luffy


# 把celery和django进行组合,需要识别和加载django的配置文件
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'luffyapi.settings.dev')
#如果只是使用了logging日志功能的话可以不写以下两句,因为logging是python提供的模块,但是将来可能使用celery来执行其他的django任务,所以我们先写上
import django
django.setup()

# 通过app对象加载配置
app.config_from_object("mycelery.config")

# 加载任务
# 参数必须必须是一个列表,里面的每一个任务都是任务的路径名称
# app.autodiscover_tasks(["任务1","任务2"])
app.autodiscover_tasks(["mycelery.sms","mycelery.mail"])

# 启动Celery的命令
# 切换目录到mycelery根目录下启动
# celery -A mycelery.main worker --loglevel=info

在需要使用django配置的任务中,直接加载配置,所以我们把注册的短信发送功能,整合成一个任务函数,代码:

from mycelery.main import app
from luffyapi.libs.yuntongxun.sms import CCP
from luffyapi.settings import constants
import logging

log = logging.getLogger("django")

@app.task(name="send_sms")
def send_sms(mobile, sms_code):
    """发送短信"""
    ccp = CCP()
    ret = ccp.send_template_sms(mobile, [sms_code, constants.SMS_EXPIRE_TIME//60], constants.SMS_TEMPLATE_ID)
    if not ret:
        log.error("用户注册短信发送失败!手机号:%s" % mobile)

在这个任务中,我们需要加载短信发送的sdk和相关的配置常量,所以我们可以直接把django中的短信发送模块和相关的常量配置文件直接剪切到当前sms任务目录中

mycelery/
├── config.py
├── __init__.py
├── main.py
└── sms/
    ├── __init__.py
    ├── tasks.py

再次启动项目即可。

最终在django里面,我们调用Celery来异步执行任务。需要完成2个步骤:

# 1. 声明一个和celery一模一样的任务函数,但是我们可以导包来解决
from mycelery.sms.tasks import send_sms

# 2. 调用任务函数,发布任务
send_sms.delay(mobile,sms_code)
# send_sms.delay() 如果调用的任务函数没有参数,则不需要填写任何内容
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值