Celery(分布式任务队列)在Python中的基本使用

Celery在Python中的基本使用

1. Celery简单介绍

1.1 简介Celery是什么?

Celery是一个基于Python开发的强大工具,旨在处理分布式异步任务队列。

1.2 具体的案例

在日常的后端对于IO阻塞较大的事件中,我们需要将事件异步执行,而不能进行同步执行。

例如:用户请求获取验证码时,我们需要向短信服务商调用请求接口去发送短信验证码,但是如果短信服务商网络出现波动,如果我们后端一直拼命的等待发送的结果,那对于用户来说,他并不知道短信到底有没有发送成功,就会疯狂的点击按钮尝试发送,所以我们应该先返回发送成功,然后将短信的发送事件添加到异步队列中,让他在慢慢执行,直到执行成功为止。

而正常来说,这件事儿我们也许会通过多线程/多进程进行提交,但是我们自己写的线程/进程逻辑,一方面来说性能优化问题,尤其是还有GIL锁对于线程限制,并且写起来也比较繁琐,所以这里我们引入了Celery,一个分布式任务队列,来处理我们的异步任务!

1.3 基本机制

Celery 通过消息机制进行通信,通常使用中间人(Broker)作为客户端和职程(Worker)调节。启动一个任务,客户端向消息队列发送一条消息,然后中间人(Broker)将消息传递给一个职程(Worker),最后由职程(Worker)进行执行中间人(Broker)分配的任务。

在这里插入图片描述

而我们要做的,就是定义好三个东西:

  1. 消息中间件(一般是RabbitMQ或者Redis)
  2. 任务(说白了,就是要干的事儿,比如是发短信还是发邮箱)
  3. 结果储存(Backend) (一般和消息中间件一样,但是不放在一个库中,例如一个在Redis的库1,一个在库2)

2. 创建消息中间件Broker及定义结果存储

2.1 定义Celery的各种参数

Celery默认使用RabbitMQ作为消息中间件,但是在这里使用我们最常用的缓存数据库Redis作为演示

创建tasks.py文件

import time
import celery

broker = 'redis://192.168.32.128:6379/8' # 定义消息中间件的存储库是 8
backend = 'redis://192.168.32.128:6379/9' # 定义结果存储库是 9

app = celery.Celery(
    'Test',
    broker=broker,
    backend=backend
)
# 创建一个celery实例

@app.task  #使用 实例.task装饰器,定义我们需要加入到消息队列的函数
def send_sms(phone,msg):
    """模拟用户发短信的需求"""
    time.sleep(2)
    print(f'给{phone}发送短信:{msg}')
    return True

2.2 启动celery服务,让其不断监控消息中间件

tasks.py同目录的终端中执行以下代码

celery -A 定义实例的py文件名(不带.py) worker -l (日志的等级)
# eg:
	celery -A tasks worker -l INFO 
    # ↑ 创建tasks.py中定义的实例配置对应的celery服务,日志等级INFO

2.3 Windows的踩坑!!

Celery 4.0 以上的版本中,必须指定以下参数

-P 其他并发池
# eg:
celery -A tasks worker -l INFO -P eventle
#  使用 Eventlet库的并发池,需要pip install eventlet
celery -A tasks worker -l INFO -P threads
#  使用线程作为并发

才能够正常运行,否则会一直阻塞不运行程序

为什么一定要指定这个参数?

官方文档中,其实已经表明了不再支持Windows

常见问题 — Celery官方文档)

Does Celery support Windows?

Answer: No.

Since Celery 4.x, Windows is no longer supported due to lack of resources.

But it may still work and we are happy to accept patches.

翻译:从4.x开始,Windows由于缺乏资源,不再受支持,但是仍然可能可以使用,我们很乐意接收补丁。

所以,默认使用的Prefork Pool并发池,不再支持Windwos,但是指定其他并发池,仍然可以使用。

3. 提交事件到消息中间件(让函数执行)

提交事件,直接调用已经被装饰器装饰过的方法.delay(参数…)就可以将事务提交

例如创建main.py

from tasks import send_sms # 导入刚刚定义的函数

result = send_sms.delay('666666', '验证码666666')
# 调用被装饰器装饰后的函数.delay(参数)即可提交任务
print(result.id) # 提交完成后,通过.id可以获取到事务的id
result_2 = send_sms.delay('888888', '验证码888888')
print(result_2.id)

直接运行后,可以发现事件已经执行

在这里插入图片描述

4. 获取执行结果

获取执行结果,需要用到celery.result下的AsyncResult类,进行获取

from tasks import app # 导入celery的实例App
from celery.result import AsyncResult # 导入AsyncResult类

async_result = AsyncResult(id='e0ed9182-7391-4992-8660-6a0711aea159',app=app)
# 获取一个异步结果实例,需要id就是提交事件的时候返回的id,app就是对应的实例App
if async_result.successful():
    """successful返回是否执行成功"""
    print(f'执行成功,结果:{async_result.result}')
elif async_result.failed():
    """successful返回是否执行失败"""
    print(f'执行失败!!')
elif async_result.status == 'PENDING':
    """successful返回任务是否还在等待"""
    print(f'任务等待被执行中...')
elif async_result.status == 'RETRY':
    """successful返回任务是否在重试阶段"""
    print(f'任务重试中...')

返回任务是否还在等待"“”
print(f’任务等待被执行中…‘)
elif async_result.status == ‘RETRY’:
“”“successful返回任务是否在重试阶段”“”
print(f’任务重试中…’)


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值