安装
pip install -U Celery
认识:
生活中的例子:我去楼下扔垃圾,扔到垃圾桶后保洁阿姨把垃圾分类掉,清空。这,就是celery
客户端:发布任务一方eg:django/flask/自己写程序
工作者(worker): 真正执行工作的这一方。具备多任务处理。具有多进程/协程。
协程库:gevent /greenlet,默认是在多进程中工作的。可以理解为进程池的模式。
任务队列(中间人):客户端将任务交给broker, 工作者从broker中拿取任务。
broker并不是由celery自己实现的,它是通过其他容器来实现的。Redis/RabbitMQ(message-queue)
Backend(第四方):工作者存放结果的地方。eg: Redis/MySQL/其他都可以。
使用流程
- 客户端定义任务:以函数方式 eg send_sms函数。
- 使得celery知道这个函数,就要先创建一个app=celery(),使用@app.task将函数进行装饰。此时,这个send_sms函数就变成了可以向任务队列里放的一个函数。
- 客户端发布任务,在任务队列broker中存放任务函数的名称。
- 当worker获取任务时,在worker中也同时存在app=celery(),也同时存在一个呗装饰过的任务函数send_sms(完整的实现任务逻辑)
- worker复用客户端的代码
- 发布任务的一方怎么发布任务:send-sms.delay()
- worker 会不断的从broker中找任务,所以会自己调用,我们不用提取任务。
- 真正在代码运行的时候,至少必须要运行三端:客户端、任务队列、worker。在celery中开始workrt命令: celery -A 定义任务的python模块。worker -l INFO(-A 启动的celery启动程序)
要注意的是:
- 启动命令时,你用的函数名.delay()方法,delay的括号中传入你要用的参数
- 先启动自己的程序
- 在启动worker时记得要和程序在同一个环境同一个目录下
- -A 后面跟的是自己定义的函数位置 比如:celery -A ihome.tasks.task_sms.send_sms 要记住你要找的是你用的那个函数
Celery的目录结构使用
在平时工作中,使用celery函数的地方还是很多的,所以我们要规定一个目录,用来专门处理这类功能
我们将celery的任务单独放到一个包中
包中含有:init文件、main文件、config文件、以及任务包(比如sms包)
-
init文件让存放celery的这个目录成为了包,方便导入
-
config :定义了celery的相关配置
BROKER_URL = "redis://127.0.0.1:6379/1" CELERY_RESULT_BACKEND = "redis://127.0.0.1:6379/2"
-
main 定义了celery,并且可以在里面从config中导入celery的配置信息和自动搜索任务的功能
from celery import Celery
from ihome.tasks import configcelery_app = Celery(“ihome”)
引入配置信息
celery_app.config_from_object(config)
自动搜寻任务(要求任务的文件名都为task)
要求在输入在列表内的目录要能直达到所定义函数的tasks文件上,并且可支持输入多个。
celery_app.autodiscover_tasks([“ihome.tasks.sms”])
-
任务包(sms包):里面存有init文件、tasks.py文件
-
tasks中书写相关函数:
from ihome.tasks.main import celery_app
from ihome.libs.yuntongxun.sms import CCP
@celery_app.task
def send_sms(to, datas, temp_id):
"""发送短信的异步任务"""
ccp = CCP()
ccp.send_template_sms(to, datas, temp_id)
在tasks中书写的函数会自动被发现。
输出的显示(Backend)
如果函数有返回值,并且装完装饰器后也依旧有return, 那么会显示返回值。
Q:如何获取返回值?
A:(1)在backend存储的位置,使用容器的方法进行获取所要的值。
A:(2)使用result.get()方法。通过get方法能获取celery异步执行的结果。get方法默认是阻塞的行为,会等到有了执行结果之后才返回。get方法也接收参数,timeout(超时时间),超过超时时间还拿不到结果,则返回。