Celery基础(异步任务、延迟任务、定时任务)

48 篇文章 0 订阅
2 篇文章 0 订阅

Celery基础(异步任务、延迟任务、定时任务)

介绍

Celery是基于Python编写的分布式异步任务框架,Celery只是用来调度任务的,其本身不具备存储任务的功能,因此需要借助像Redis、消息队列、数据库之类的存储工具,官方推荐的消息队列是RabbitMQ,而我们使用Redis

使用场景

  • 异步任务
    • 视频转码、邮件发送、消息推送等
  • 定时任务
    • 定时发送消息之类
  • 延迟任务
    • 提交任务后,在一段时间后再执行某个任务

Celery架构

Celery使用的是典型的生产者消费者模式,其主要由以下部分组成:

image-20240516192718650

  • Celery Beat:任务调度器,Beat进程会读取配置文件的内容,并周期性的将配置中到期需要执行的任务发送给消息队列
  • Producer:需要在队列中进行的任务,一般由用户、触发器或其他操作将任务拉入队,然后交由workers进行处理。调用了 Celery 提供的 API、函数或者装饰器而产生任务并交给任务队列处理的都是任务生产者
  • Broker:消息中间件,在这里指的是任务队列本身,Celery扮演生产者和消费者角色,brokers就是生产者和消费者存放/拿取产品的地方(队列)
  • Celery Worker:执行任务的消费者,从队列中取出任务并执行。通常会在多台服务器运行多个消费者来提高执行效率
  • Result Backend:任务处理完后保存状态信息和结果,以供查询,Celery 默认已支持 Redis、RabbitMQ、MongoDB、Django ORM、SQLAlchemy 等方式

启动指令

终端使用命令时必须将路径定位到app文件所在的包中

# 启动worker
celery -A tasks worker -l info -P eventlet 
# 启动beat
celery -A tasks beat -l info

快速使用

官网

Python版本支持:

  • Celery version 5.3.5 runs on:
    • Python (3.8, 3.9, 3.10, 3.11, 3.12)
    • PyPy3.9+ (v7.3.12+)
  • Python 3.7: Celery 5.2 or earlier.
  • Python 3.6: Celery 5.1 or earlier.
  • Python 2.7: Celery 4.x series.
  • Python 2.6: Celery series 3.1 or earlier.
  • Python 2.5: Celery series 3.0 or earlier.
  • Python 2.4: Celery series 2.2 or earlier.

安装

pip install celery
pip install redis
# win平台运行,如果是mac,linux不需要
pip install eventlet

创建tasks主文件

# tasks.py
from celery import Celery
from redis import Redis

broker = 'redis://127.0.0.1:6379/1'
backend = 'redis://127.0.0.1:6379/2'

app = Celery('tasks',broker=broker,backend=backend)

@app.task
def add(x,y):
    return x+y

add_task.py 提交任务

# add_task.py
from tasks import add
from tasks import app

# 同步调用(直接打印结果)
res=send_email()
print(res)

# 异步调用
res = add.delay(10, 20)
print(res.id)

启动worker

celery -A tasks worker -l info -P eventlet 
  • tasks:注册app的py文件名
  • -P:Windows系统

获取任务id

c48af49b-5169-4d5b-b2ab-13ad5f4d264c

结果存储并查看

# get_res.py
from celery.result import AsyncResult
from tasks import app

id = 'c48af49b-5169-4d5b-b2ab-13ad5f4d264c'

result = AsyncResult(id=res.id, app=app)
if result.successful():
    result = result.get()
    print(result)
elif result.failed():
    print('任务失败')
elif result.status == 'PENDING':
    print('任务等待中被执行')
elif result.status == 'RETRY':
    print('任务异常后正在重试')
elif result.status == 'STARTED':
    print('任务已经开始被执行')
    
# 结果:30

目录结构

项目名
    ├── celery_task  	# celery包
    │   ├── __init__.py # 包文件
    │   ├── tasks.py  	# app主文件
    │   └── user_tasks.py    # 所有任务函数
    	└── order_tasks.py   # 所有任务函数
    ├── add_task.py  	# 添加任务
    └── get_res.py   	# 获取结果

异步任务

也就是.delay方法

# tasks.py
# 创建app和需要执行的函数add
from celery import Celery
from redis import Redis

broker = 'redis://127.0.0.1:6379/1'
backend = 'redis://127.0.0.1:6379/2'

app = Celery('tasks',broker=broker,backend=backend)

@app.task
def add(x,y):
    return x+y

# get_res.py
# 模拟异步任务的提交和获取
from tasks import add
from celery.result import AsyncResult
from tasks import app

def get_task(id):
    result = AsyncResult(id=id, app=app)
    if result.successful():
        result = result.get()
        print(result)
    elif result.failed():
        print('任务失败')
    elif result.status == 'PENDING':
        print('任务等待中被执行')
    elif result.status == 'RETRY':
        print('任务异常后正在重试')
    elif result.status == 'STARTED':
        print('任务已经开始被执行')

def set_task(num1,num2):
    res = add.delay(num1, num2)
    return res.id
    
# 批量提交、执行任务
# 实际情况可能会因为刚提交任务就提取,导致任务还在等待中,
# 因此为了更好的模拟可以在get_task中加入延迟
get_task(set_task(1,2))
get_task(set_task(2,3))
get_task(set_task(3,4))

延迟任务

# add_task.py
from tasks import add
from datetime import datetime, timedelta

# 获取当前utc时间+5秒
eta = datetime.utcnow() + timedelta(seconds=5)
# 创建延迟任务 五秒后执行
res = add.apply_async(args=[5, 6], eta=eta)

image-20240516201640843

定时任务

# celerys.py
from celery import Celery

broker = 'redis://127.0.0.1:6379/0'
backend = 'redis://127.0.0.1:6379/1'
app = Celery('celery', broker=broker, backend=backend)

# 命令:
# celery -A add_tasks beat -l info
@app.task
def add(x, y):
    return x + y
# add_tasks.py
from datetime import timedelta
from celery.schedules import crontab
from tasks import app

# 命令:
# celery -A celerys worker -l info -P eventlet
app.conf.beat_schedule = {
    'add-task': {
        # 要执行的方法所在的路径
        'task': 'scripts.tasks.add',
        # 每隔三秒启动一次
        'schedule': timedelta(seconds=3),
        # 参数
        'args': (100, 200),
    },
}

定时任务必须同时启动beat和worker(可以在两个终端)

celery -A add_tasks beat -l info
celery -A celerys worker -l info -P eventlet
  • add_tasks:这个参数必须是app.conf.beat_schedule所在的py文件
  • 21
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Celery是一个Python的分布式任务队列框架,它可以用来实现异步任务的调度与执行。使用Celery,你可以将耗时的任务放入任务队列中,然后由后台的工作进程异步执行,这样可以提高系统的并发能力和响应速度。 要使用Celery,首先需要安装Celery库。你可以使用pip命令进行安装: ``` pip install celery``` 接下来,你需要创建一个Celery实例,并定义任务函数。任务函数可以是任何可调用对象,通常是一个Python函数。例如,下面是一个简单的示例: ```pythonfrom celery import Celery# 创建Celery实例app = Celery('myapp', broker='redis://localhost:6379/0') # 定义任务函数@app.taskdef add(x, y): return x + y``` 在上面的示例中,我们创建了一个名为`myapp`的Celery实例,并指定了一个Redis作为消息代理(broker)。然后,我们定义了一个名为`add`的任务函数,使用`@app.task`装饰器来将其注册为Celery任务。 接下来,你可以使用`delay()`方法调用任务函数,将任务放入任务队列中异步执行: ```pythonresult = add.delay(4,6) ``` 在上面的示例中,我们使用`delay()`方法调用了`add`任务,并传递了两个参数4和6。这会将任务添加到Celery任务队列中,并返回一个`AsyncResult`对象,你可以使用它来获取任务的执行结果。 当任务被放入任务队列后,你需要启动Celery的工作进程来执行任务。可以使用以下命令启动工作进程: ``` celery -A myapp worker --loglevel=info``` 上面的命令中,`-A`参数指定了Celery实例所在的模块(在这个例子中是`myapp`),`--loglevel=info`参数指定了日志级别为info。 这只是Celery的一些基本用法,还有很多其他功能和配置可以探索。你可以查阅Celery的官方文档来获取更多详细信息:https://docs.celeryproject.org/

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值