celery 使用详解

て烟熏妆下的殇ゞ 提交于 2019-12-03 17:29:29

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创建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)

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!