Celery 的使用教程

介绍 celery
1.简介

Celery 是一个简单、灵活且可靠的,处理大量消息的分布式系统,专注于实时处理的异步任务队列,同时也支持任务调度。

2.引入使用背景

在程序的运行过程中,我们经常会碰到一些耗时耗资源的操作,为了避免它们阻塞主程序的运行,我们经常会采用多线程或异步任务。
比如:

  1. 例子 a: 在 Web 开发中,对新用户的注册,我们通常会给他发一封激活邮件,而发邮件是个 IO 阻塞式任务,如果直接把它放到应用当中,就需要等邮件发出去之后才能进行下一步操作,此时用户只能等待再等待。更好的方式是在业务逻辑中触发一个发邮件的异步任务,而主程序可以继续往下运行。
  2. 例子 b: 接口自动化测试平台中,当选择 N 条 case 后点击执行按钮,因为运行选择的多条 case 是一个比较耗时的过程,所以不可能在点击按钮后,页面一直处于等待运行结果的状态,那样会给用户一个页面卡住或者夯住的体验,所以运行用例的过程就应该是一个异步任务去处理。
3.结构图

Celery 是一个强大的分布式任务队列,它可以让任务的执行完全脱离主程序,甚至可以被分配到其他主机上运行。我们通常使用它来实现异步任务(async task)和定时任务(crontab)。它的架构组成如下图:

celery 结构图

4.名词介绍
1、Task

Task就是你要做的事情,也称为任务,例如一个注册流程里面有很多任务,给用户发验证邮件就是一个任务,这种耗时任务可以交给Celery去处理,还有一种任务是定时任务,比如每天定时统计网站的注册人数,这个也可以交给Celery周期性的处理。

2、Broker

Broker 的中文意思是经纪人,指为市场上买卖双方提供中介服务的人。在Celery中它介于生产者和消费者之间经纪人,这个角色相当于数据结构中的队列。例如一个Web系统中,生产者是处理核心业务的Web程序,业务中可能会产生一些耗时的任务,比如短信,生产者会将任务发送给 Broker,就是把这个任务暂时放到队列中,等待消费者来处理。 消费者是 Worker,是专门用于执行任务的后台服务。Worker 将实时监控队列中是否有新的任务,如果有就拿出来进行处理。Celery 本身不提供队列服务,一般用 Redis 或者 RabbitMQ 来扮演 Broker 的角色。

3、Worker

Worker 就是那个一直在后台执行任务的人,也称为任务的消费者,它会实时地监控队列中有没有任务,如果有就立即取出来执行。

4、Beat

Beat 是一个定时任务调度器,它会根据配置定时将任务发送给 Broker,等待 Worker 来消费。

5、Backend

Backend 用于保存任务的执行结果,每个任务都有返回值,比如发送邮件的服务会告诉我们有没有发送成功,这个结果就是存在Backend中,当然我们并不总是要关心任务的执行结果

使用讲解
步骤大致如下:
  • 创建 Celery 实例
  • 定义 worker
  • 启动 broker (redis 或者 rabbitmq)
  • 将定义的 worker 监听 broker

手动发送task执行异步任务

创建 Celery 实例及定义 worker 以及申明 broker(这里 broker 以 Redis 举例 )

# tasks.py
import time
from celery import Celery


# 申明获取task来源以及消费者执行task结果的redis
broker = 'redis://127.0.0.1:6379/1'
backend = 'redis://127.0.0.1:6379/2'

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


@app.task
def add(x, y):
	print(f"开始执行时间为:{time.time()}")
	time.sleep(5)     # 模拟耗时操作
	print(f"结束执行时间为:{time.time()}")
	return x + y


@app.task
def push_email(name):
	print(f"准备给 {name}发送邮件!")
	time.sleep(5)
	print(f"邮件发送完成!")
	return True
# 定义生产者 producer.py 
from tasks import add, push_email
import random


def do_add(x, y):
	res = add.delay(x, y)
	print(res.id)
	return {"code": 200, "mag": "success"}


def registered():
	name = input("请输入注册人员名称:")
	push_email.delay(name)
	return {"code": 200, "msg": f"恭喜{name}注册成功! 请查看邮箱点击确认链接进行校验。"}


if __name__ == '__main__':
    # 这里产生 100 个 task;
	for i in range(100):
		print(do_add(random.randint(1, 1000000), random.randint(1000000, 2000000)))
	# 这里再新加一个 task
	print(registered())

可以中途查看 broker 中的剩余任务个数

# test_redis.py (查看中间件中的剩余任务个数)
from redis import Redis

r = Redis(host="127.0.0.1", port=6379, db=1)
# r = Redis(host="10.50.255.104", port=6379, db=1)

task_list = r.lrange("celery", 0, -1)
print(f"任务个数:{len(task_list)}")

# for i in task_list:
# 	print(i)
  • 启动 broker
    备注
  1. 这里生产者或消费者可以和 broker 部署在不同机器上,只要保证部署的机器彼此能够正常通信即可,本例是在都部署在本地机器上!
    机器安装redis或者rabbitmq步骤不做详述。
  2. 使用该生产者模型时切记几者的启动顺序:
    1. 首选应该先启动 broker ,它是接受任务(task)的对象,如果不首先启动直接调用生产者或者定时任务,那么任务就不会出现在 broker 中,消费者也就没办法进行消费;
    2. 其次启动消费者并监听broker,这样只要broker 中出现任务task, 消费者就会立即进行消费;
    3. 上述两步完成就可以启动生产者进行对broker中分发任务,当然也可以通过定时任务分发任务;
redis-server /usr/local/etc/redis.conf

启动Redis成功

  • 将定义的 worker 监听 broker
celery worker -A tasks -c 5 -l info

补充说明

  1. tasks 代表的是 定义 woker 的文件名称,注意不带文件后缀;
  2. -c 5 代表的是指定执行队列任务子进程数,不指定时默认为 CPU 内核数;
    在这里插入图片描述
  • 执行生产者即可给 broker 发送 task 任务指令;
python producer.py
至此框架基础使用就已经介绍完毕,下面有一个demo代码做演示
  • 我们首先按照上述流程把框架搭建起来并启动 redis;
  • 然后执行上述生产者代码;
  • 执行查看 redis 中任务代码;
    在这里插入图片描述
    这里肯定有人问生产者不是一共分发了100+1 个任务吗?为啥 redis 中查询结果只有100个?其实在执行生产者代码后,额外加1的那个task还没有被扔到 redis中,看下图即可:
    在这里插入图片描述
    第101个task的代码还没走完,需要输入名称后,该task才会生成;这里我们输入科比再去调用查询结果如下:
    在这里插入图片描述
    在这里插入图片描述
  • 我们最后在执行消费者,保证woker去监听 broker,这样生产者产生的任务就会被消费掉;
    在这里插入图片描述
    这里就能看到有同时有5个 worker去消费任务,直到所有的任务被执行完成;

补充:可以使用flower库查看每个task的执行情况
使用命令:
celery -A tasks flower
在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
当然,我可以给你一个简单的 Celery 使用示例。Celery 是一个强大的分布式任务队列框架,常用于处理异步任务和定时任务。 首先,你需要安装 Celery。你可以使用 pip 命令来安装: ```bash pip install celery ``` 接下来,创建一个 Celery 应用。在你的项目中创建一个名为 `tasks.py` 的文件,并添加以下内容: ```python from celery import Celery # 创建 Celery 应用 app = Celery('tasks', broker='redis://localhost:6379/0') # 定义任务 @app.task def add(x, y): return x + y ``` 这里我们使用Redis 作为消息代理(broker),你也可以选择其他的消息代理,比如 RabbitMQ。 接下来,在你的项目根目录下创建一个名为 `celery_worker.py` 的文件,并添加以下内容: ```python from tasks import app # 启动 Celery 工作进程 if __name__ == '__main__': app.worker_main() ``` 现在,你可以启动 Celery 工作进程了。打开终端,进入你的项目根目录,运行以下命令: ```bash celery -A celery_worker worker --loglevel=info ``` 这样,Celery 工作进程就会启动并开始监听任务了。 最后,你可以在你的代码中调用 `add` 任务,示例如下: ```python from tasks import add result = add.delay(4, 6) # 异步调用任务 print(result.get()) # 获取任务结果 ``` 这样就完成了一个简单的 Celery 使用示例。你可以根据自己的需求定义更多的任务,并在你的代码中调用它们。希望对你有帮助!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值