celery架构介绍和基本使用

一、 Celery架构介绍

  • 分布式异步任务框架,可以支持大量任务的并发执行(celery服务主要为其他项目服务提供异步解决任务需求的)
  • 可以不依赖任何服务器,通过自身命令,启动服务,内部支持socket。
  • 官方不支持Windows,目前装一个第三方支持包eventlet,让它在Windows上运行。
  • 官方中文文档:http://docs.jinkan.org/docs/celery/

  1. 使用场景

  • 异步执行:解决耗时任务,将耗时操作提交给celery去异步执行,如发送短信/邮件、消息推送、音频处理等(区分同步任务)
  • 延迟执行:解决延迟任务,比如延迟推送消息,订单30分钟内未支付,订单自动取消等
  • 定时执行:解决周期任务,比如每天数据统计,每天定时发送邮件等

  2. 组成部分

  • broker:任务中间件,用户提交的任务,存在这个里面(redis缓存数据库,rabbitmq是专业的消息队列)
  • worker:任务执行者,消费者,真正执行任务的进程(可能有多个worker)
  • backend:任务结果存储,任务执行后的结果。(也可能是完成的任务,也可能是没有完成的结果,抛异常的结果等,它们放在redis,rebbitmq,甚至是关系型数据库中)

 

 User用户可以是任何东西,可以是Django,也可以是个脚本

 

 

二 、Celery的简单使用

 

 1. 安装

pip install celery==5.1.2

 

2. 创建任务文件:celery_task.py

from celery import Celery
import time

# backend='redis://:密码@127.0.0.1:6379/1'   如果有密码,固定写法
# 任务提交到1,worker执行完之后,结果存到2
broker = 'redis://127.0.0.1:6379/1'  # redis地址   6379端口的第一个库
backend = 'redis://127.0.0.1:6379/2'  # redis地址  6379端口的第二个库


# 1. 实例化得到一个对象
app = Celery(__name__, broker=broker, backend=backend)


# 2. 写任务
# 使用装饰器包裹任务(函数)
@app.task()
def add(a, b):
    time.sleep(2)   # time睡两秒
    return a+b

 

3. 提交任务:celery_submit.py

 ① 同步执行(直接得到结果)

'''
普通的同步任务:
定义两个变量,得到一个对象,用对象一装饰就装饰了一个任务,下面可以写一堆任务。接下来再把任务提交到broker消息中间件中,再调函数同步执行
'''
import celery_task

res = celery_task.add(2, 3)     # 普通的同步任务,同步执行任务。
print(res) # 5

 

 ② 异步任务(得到任务ID号)

  • 第一步,提交 (使用任务名.apply_async(参数))    # 结果是任务id号,唯一标识这个任务
  • 第二步,让worker执行 -> 结果存到redis
  • 第三步,查看任务执行结果

异步提交任务:

import celery_task

# 有参数传参数,没有参数就不用传。可以使用两种方式传
# res = celery_task.add.apply_async(args=[2,3])   # 按位置传参
res = celery_task.add.apply_async(kwargs={'a':2, 'b':3})    # 按关键字传参
print(res)  # cb745b27-b848-4229-8e1c-408d7343fb83  结果是任务id号,唯一标识这个任务

 

在redis的db1中可以查看到celery的任务ID号:

 

 4. 执行任务:通过worker命令启动执行

① 非Windows系统

5.x之前:celery worker -A celery_task -l info

5.x以后:celery -A celery_task worker -l info

② Windows系统
安装eventlet:

> 通过命令安装

 

pip install eventlet

>通过pycharm安装 

安装之后,在任务文件的路径下 输入启动命令:

5.x之前:celery worker -A celery_task -l info  -P eventlet   

5.x以后:celery -A celery_task worker -l info  -P eventlet

 (l后面跟的是日志的级别,celery_task 是py文件名,如果是包管理,就是包名)

 

 

 启动后执行:

 

 在redis中查看到执行结果:

 

 5. 查看任务结果:celery_result.py

# 查看任务结果
from celery_task import app

from celery.result import AsyncResult

id = 'cb745b27-b848-4229-8e1c-408d7343fb83'
if __name__ == '__main__':
    a = AsyncResult(id=id, app=app) # 实例化等到一个对象,id就是上面的那个id,app就是刚刚celery_task中实例化得到的app
    if a.successful():  # 如果成功
        print('任务执行成功了')
        result = a.get()  # 拿到异步任务执行的结果
        print(result)
    elif a.failed():
        print('任务失败')
    elif a.status == 'PENDING':
        print('任务等待中被执行')
    elif a.status == 'RETRY':
        print('任务异常后正在重试')
    elif a.status == 'STARTED':
        print('任务已经开始被执行')

 

 

posted @ 2022-11-23 15:30  Tutu007  阅读(252)  评论(0编辑  收藏  举报