使用 Celery + Redis + Eventlet 实现 Python 异步编程(Windows 环境)
一、环境搭建与依赖安装
1. 安装依赖包
pip install celery redis eventlet
celery
:异步任务队列框架。redis
:作为消息中间件(Broker)和结果存储(Backend)。eventlet
:用于 Windows 环境下的协程支持(解决多进程兼容性问题)。
2. 启动 Redis 服务
- 下载 Windows 版本 Redis:
https://github.com/tporadowski/redis/releases
- 启动 Redis 服务:
redis-server.exe redis.windows.conf
二、代码实现
1. 定义 Celery 任务(tasks.py
)
import time
from celery import Celery# 创建 Celery 实例,指定 Broker(Redis)和结果存储(Redis)
broker = 'redis://127.0.0.1:6379/1'
backend = 'redis://127.0.0.1:6379/2'
app = Celery('tasks',broker=broker, # Redis 队列backend=backend # Redis 结果存储
)@app.task
def add(x, y):"""异步加法任务"""print("x+y的结果:", x+y)time.sleep(1)return x + y
2. 调用任务(demo.py
)
from tasks import addresult = add.delay(62, 4) # 异步调用任务,返回 AsyncResult 对象
print(result.get()) # 阻塞等待任务结果
三、问题现象与解决方案
1. 问题:result.get()
阻塞无输出
现象描述
执行 demo.py
时,result.get()
会一直阻塞,直到启动 Celery Worker 后才输出结果。
原因分析
- Celery 的异步执行流程:
-
add.delay(62, 4)
将任务发送到 Redis 队列(Broker)。
-
Worker 未启动 时,任务无法被消费,结果不会写入 Backend。
-
result.get()
会尝试从 Backend 获取结果,但因结果未写入,会 无限等待。
-
解决方案
- 启动 Celery Worker:
celery -A tasks worker -l info -P eventlet
-
-P eventlet
:指定使用 Eventlet 协程池(Windows 必须)。 -
启动后,Worker 会从 Redis 队列中拉取任务并执行,结果写入 Redis Backend。
-
result.get()
会立即返回结果。
-
四、Celery 异步原理详解(测试工程师友好版)
1. Celery 的核心架构
Celery 是一个 生产者-消费者 模型,由三部分组成:
-
Broker(消息中间件)
- 作用:存储待执行的任务队列。
- 类比:快递公司的分拣中心,接收包裹(任务)并分发给快递员(Worker)。
-
Worker(任务执行单元)
- 作用:从 Broker 拿取任务并执行。
- 类比:快递员,负责派送包裹(执行任务)。
-
Backend(结果存储)
- 作用:存储任务执行结果。
- 类比:快递柜,任务完成后将结果存入,供用户(调用方)查询。
2. 异步执行流程图解
调用 add.delay(62, 4) → 任务写入 Redis(Broker)↓
Worker 启动后从 Redis 拿取任务 → 执行 add(62, 4)↓
执行结果写入 Redis(Backend)↓
调用 result.get() → 从 Redis 读取结果 → 输出 66
3. 为什么需要 Eventlet?
- Windows 的限制:
Windows 不支持多进程(multiprocessing
),而 Celery 默认使用多进程模式。 - Eventlet 的作用:
通过 协程(Coroutine) 实现并发,模拟多线程效果,解决 Windows 环境下 Worker 启动失败的问题。
五、测试工程师的异步思维训练
1. 同步 vs 异步
场景 | 同步(阻塞) | 异步(非阻塞) |
---|---|---|
发送邮件 | 用户等待邮件发送完成再继续操作 | 邮件在后台发送,用户可继续操作 |
文件处理 | 用户必须等待文件处理完成 | 处理完成后通知用户 |
2. 异步编程的核心思想
- 事件驱动:任务遇到 I/O(如网络请求、文件读写)时,主动让出 CPU,执行其他任务。
- 事件循环:不断检查任务状态,调度协程执行(如
asyncio
的事件循环)。
六、完整示例验证
1. 启动 Redis
可参考往期文章:Redis原理与Windows环境部署实战指南:助力测试工程师优化Celery调试
redis-server.exe redis.windows.conf
2. 启动 Celery Worker
celery -A tasks worker -l info -P eventlet
3. 运行 demo.py
python demo.py
输出结果:
66
七、总结
1. 关键点回顾
- Celery + Redis:生产者将任务写入 Redis,Worker 从 Redis 拿取任务并执行,结果存回 Redis。
- Eventlet 的必要性:解决 Windows 环境下的多进程兼容性问题。
- 异步的本质:通过事件驱动和协程实现高并发,避免阻塞主线程。
2. 测试工程师的实践建议
- 验证异步任务:通过
result.get()
验证结果是否写入 Backend。 - 监控任务状态:使用
result.status
查看任务状态(PENDING
/SUCCESS
/FAILURE
)。 - 调试技巧:检查 Redis 中的键值对,确认任务是否被正确处理。
通过以上步骤,你可以在 Windows 环境下轻松实现 Celery + Redis + Eventlet 的异步编程方案。异步编程的核心在于“让等待时间做其他事”,而 Celery 让你无需关心底层细节,专注于任务逻辑本身!