Celery

2 篇文章 0 订阅
1 篇文章 0 订阅

Celery

执行流程

1.实例化app 2.app装饰几个任务 3.其他函数导入这个任务并使用 函数.delay执行(此时并不是真正的执行而是将它放入broker中,如果这个时候worker启动,或者已经启动,他就立即执行) 4.得到结果放入redis中

程序运行

启动任务建议参考官方文档

image-20201230195430247

由于没有任务所以程序一直停在哪里

image-20201230195950244

添加任务

celery_test.py

@app.task  # 用此装饰器装饰
def add(x, y):
    print(f'正在计算{x},{y}的和.....')
    return x + y

但是此方法并没有被添加到broker中,如果我们要将他添加到broker中

基本使用

获取id-方法一

1.celery -A celery_test worker -l info让celery框架先跑起来
from celery import Celery

# broker任务队列
broker = 'redis://127.0.0.1:6379/1'

# redis下的第二个库,放在一个库的其实也没关系,也不会乱,但是这样更容易区分
backend = 'redis://127.0.0.1:6379/2'  # 结构存储,执行完的结果存这里
app = Celery(__name__, broker=broker, backend=backend)


# 用命令执行
# celery -A celery_test worker -l info


# 添加任务
@app.task  # 用此装饰器装饰
def add(x, y):
    print(f'正在计算{x},{y}的和.....')
    return x + y

2.执行函数名.delay模块
from celery_test import add
# add(11,23)  # 直接执行不会被添加到broker中
add.delay(3,4) 
3.得到如下情况

image-20201231171709675

获取id-方法二

执行函数名.delay模块
from celery_test import add
# add(11,23)  # 直接执行不会被添加到broker中
result = add.delay(3,4)   # delay执行返回的就是uuid号
print(result)
------------------------------------------------------
7d27cc54-51e0-4ce6-87ed-805d9b7ae141

执行

from celery_test import app

from celery.result import AsyncResult


# 这是delay任务执行后 celery接收到并生成的uuid
id = '9f1d31a1-90b3-44ab-88f0-35efc6022d6b'
if __name__ == '__main__':
    # async 现在是内置的关键字,用作声明后面的函数为 异步函数
    
    # 这个类的作用是查询任务状态
    # 也就是通过id和被app装饰的tast任务来定位,并查询状态,如果其中有错误,
    # 就会按照下面自定义的显示状态内容。
    async_one = AsyncResult(id=id, app=app)
    # 成功执行
    if async_one.successful():
        # 通过实例化的get方法拿到结果
        result = async_one.get()
        print(result)
    elif async_one.failed():
        print('任务失败')
    elif async_one.status == 'PENDING':
        print('任务等待被执行')
    elif async_one.status == 'RETRY':
        print('任务异常后正在重试')
    elif async_one.status == 'STARTED':
        print('任务已经开始被执行')
        
        
-------------------------------------------------
7

推荐使用

1.创建一个celery的包,在包里存放相关的py文件,里面必须有一个名叫celery.py文件celery_task.py里面存放实例化的app,然后一个任务为一个py文件,交给app管理。

此时celery_task可以称之为一个celery项目

image-20210105201024863

# celery.py

from celery import Celery

broker = 'redis://localhost:6379/9'
backend = 'redis://localhost:6379/10'

# include是一个反射,里面是一个路径,只有被注册才能被管理
app = Celery(__name__, broker=broker, backend=backend, include=['celery_task.task1', 'celery_task.task2 '])
# task1.py
# 因为都在包内  所以可以使用 . 相对导入,
from .celery import app


@app.task
def add(x, y):
    print(f'正在计算{x}和{y}的和......')
    return x + y
# task2.py

from .celery import app

@app.task
def multiply(x, y):
    print(f'正在计算{x}和{y}的积......')
    return x * y

然后我们可以根据路径的相对导入来调用被celery管理的函数,我们启动的时候就要换一种方式了切换到scripts文件夹下启动celery项目包

image-20210105204133981

然后就启动了

image-20210105204216683

添加任务

from celery_task.task1 import add
# 只要能够通过这个路径导入模块执行delay就可以了

res = add.delay(99,88)
print(res)  # 右键执行
-------------------------------------------
13f6b078-fd37-422d-934c-44ced9ae7705

image-20210105213337040

结果仓库中

image-20210105213426700

ps:如果celery后台没有启动则只有两个(celery -A celery_test worker -l info)

image-20210105213915879

延时任务

添加延时任务

from datetime import datetime, timedelta

from celery_task.task1 import add

# 强类型
# 取了utc的当前时间 + 延迟时间(时间类型格式) 所以可以直接和时间格式相加
print(timedelta(seconds=10))
eta = datetime.utcnow() + timedelta(seconds=10)

# 执行延时任务
# add里需要几个参数 args里就放多少参数,然后后面etc存放utc时间,但是我们这里是东八区
# 如果我们直接填当前时间 会+8个小时
add.apply_async(args=(11, 88), eta=eta)
-------------------------------------------------
0:00:10

image-20210105224313260

image-20210105224405387

timedelta相关参数介绍

image-20210106081733643

image-20210106081047646

定时任务

既然是定时任务,那么认任务肯定是之前就被添加的,所以我们要放在 包下的celery.py

from celery import Celery

broker = 'redis://localhost:6379/9'
backend = 'redis://localhost:6379/10'

# include是一个反射,里面是一个路径,只有被注册才能被管理
app = Celery('Django', broker=broker, backend=backend, include=['celery_task.task1', 'celery_task.task2'])

# 执行定时任务
# 时区
app.conf.timezone = 'Asia/Shanghai'
# 是否使用UTC
app.conf.enable_utc = False

# 任务的定时配置
from datetime import timedelta

from celery.schedules import crontab

app.conf.beat_schedule = {
    # 任务名称
    'add_task': {
        # 函数路径
        'task': 'celery_task.task1.add',
        # 每五秒执行函数add
        'schedule': timedelta(seconds=5),
        # 如果对定时要求的更复杂
        # 'schedule':crontab(hour=8, day_of_week=1)  # 每周一的八点执行
        
        # 传参
        'args': (1, 2)
    }
}

此时我们执行celery -A celery_task worker -l info是不行的任务并不会跑起来

image-20210106085334065

任务并没有提交,worker只是在等待,所以我们还需要一条命令将任务提交 启动beat

celery -A celery_task beat -l info

image-20210106090021460

这个时候任务才是真正被执行

image-20210106090347815

我们也可以再redis中看到结果-执行了五次

image-20210106090430816

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值