celery
是啥?
由python 编写 的异步生产者消费者设计模式下 的实例
举个例子:
现有两个进程 生产者进程A 消费者进程B
现在的情况是
逻辑推导:
A 产出栗子 B 要吃栗子 那么这两个进程必然是 B依赖于A 耦合度很高且是一个耗时操作
B -----> (发送请求给A)------->(等待A 产出栗子也许会很久)------->(A响应栗子给B)------->(B得到栗子)
B 可能是个很多服务的集成后台之类很忙大忙人不想一直等等等
那么 celery 的任务就是 替B 去等
逻辑推导:
A 产出栗子 B 要吃栗子 C celery
B (替我去取栗子)-----> C(发送请求给A)------->(等待A 产出栗子也许会很久)------->(A响应栗子给C)------->(B得到栗子) (C 可以去把栗子存在一个地方B直接去取就好了)
那么celery 的本质知道了:一个中间人角色 ,类似快递小哥,跑腿的
作用:
1 防止线程阻塞提高性能
2低耦合解耦 高内聚 高复用
好处 ::每分钟可以实现数以百万的任务
特点: 使用消息队列(broker )在客户端和消费者之间协调
主体在消息队列 还有 协调 两端可以有多个
好的,现在说celery 的结构
Celery的架构由三部分组成,消息中间件(message broker),任务执行单元(worker)和任务执行结果存储(task result store)组成。
消息中间件(message broker): 这个很好理解 ,B指派给C 的任务可能不只一件,所以celery 要把任务存起来一件一件去执行 ,存储一般是用消息队列结构的,celery 本身是不带存储空间的需要指派位置存 包括,RabbitMQ,Redis,MongoDB等
ps : 队列也是一种数据结构 , 表现形式为一段进入,一段出 先进先出, 不能再中间插入 ,类似管道
任务执行单元(worker): Worker是Celery提供的任务执行的单元,worker并发的运行在分布式的系统节点中 (快递小哥本体)
任务执行结果存储(task result store):小哥把东西要放到快递柜咯 这里也要用到其他服务 包括Redis,MongoDB,Django ORM,AMQP等
简单来说就是 broker 收集任务(收件)worker 执行任务 存在 task result store (派送)
这里主要使用redis
celery 简单配置
# 安装celery sudo pip install celery -i https://pypi.douban.com/simple ------配置信息 tasks.py------- BROKER_URL = 'redis://localhost:6379/0' # 格式 redis://:password@hostname:port/db_number 不过redis 一般不设密码 from celery import Celery app = Celery("tasks", broker=BROKER_URL) @app.task def add(x,y): return x,y ----------启动------ $ celery -A tasks worker --loglevel=info #查询文档,了解到该命令中-A参数表示的是Celery APP的名称,这个实例中指的就是tasks.py,后面的tasks就是APP的名称,worker是一个执行任务角色,后面的loglevel=info记录日志类型默认是info,这个命令启动了一个worker,用来执行程序中add这个加法任务(task)。
启动成功效果展示
celery 配合 django 使用
项目结构
项目结构
1安装
pip install -U celery
2.1定义 celery_tasks包
2.2 创建celery 实例 启动文件
main.py ------------ # celery启动文件(独立于项目的启动文件单独启动) from celery import Celery # # 创建celery实例 celery_app = Celery('abc') # 加载配置 celery_app.config_from_object('celery_tasks.config')
2.3 加载 celery配置 (celery_tasks.config)
# 指定消息队列的位置redis上存放队列 broker_url = 'redis://192.168.103.210/7'
解耦出来的业务 可以放在celery 的子任务夹里面
注册任务
-----回到main 文件------- .......... ....... # 自动注册celery任务 celery_app.autodiscover_tasks(['celery_tasks.sms'])
定义任务
案例: 容联云通信接口调用
# 加上装饰器代表载入进去 name:异步任务别名 @celery_app.task(name='ccp_send_sms_code') def ccp_send_sms_code(self, mobile, sms_code): """ 发送短信异步任务 :param mobile: 手机号 :param sms_code: 短信验证码 :return: 成功0 或 失败-1 """ send_ret = CCP().send_template_sms(mobile, [sms_code, constants.SMS_CODE_REDIS_EXPIRES // 60], constants.SEND_SMS_TEMPLATE_ID) return send_ret
启动clerery
$ celery -A celery_tasks.main worker -l info
tornado + celery
因为tornado web框架 部分基本仿照了django 所以celery 使用和 django 也是类似的
结构·
-------config 文件-------------- # celery BROKER_URL = 'redis://127.0.0.1:6379/2' CELERY_RESULT_BACKEND = 'redis://127.0.0.1:6379/2' CELERY_TIMEZONE = 'Asia/Shanghai' CELERY_TASK_SERIALIZER = 'pickle' CELERY_RESULT_SERIALIZER = 'json' CELERY_TASK_RESULT_EXPIRES = 60 * 60 * 24 CELERY_ACCEPT_CONTENT = ['json', 'pickle'] CELERY_IMPORTS = ( 'celery_tasks.remove_files.tasks', )
-----main -------- from celery import Celery from . import config import os app = Celery('task') app.config_from_object(config)
启动clerery
$ celery -A celery_tasks.main worker -l info
现在celery 服务全部启用了 只需要在你的项目里面导包调用他就好了
# 解耦处调用该方法时 delay 是celry 自带的方案可以监听任务的状态 ccp_send_sms_code.delay(**kwars)