第 14 章 异步任务 Celery
学习目标
学完本章,你应该能:
- 理解为什么需要异步任务队列
- 掌握 Celery 的核心组件(worker / beat / flower)
- 知道如何启动和调用异步任务
一、为什么需要异步任务
有些操作很耗时(发邮件、生成报表、批量导入数据),如果让接口同步执行,用户得干等几十秒甚至更久,还会阻塞服务器。
解决方案:把耗时操作丢给"后台任务队列",接口立即返回"任务已提交",后台慢慢执行。
fba 用 Celery 实现这个能力。
Celery:Python 生态最流行的分布式异步任务队列框架,负责接收任务、分发给 worker 执行、记录结果。
同步 vs 异步对比
二、Celery 的核心组件
| 组件 | 作用 | 类比 |
|---|---|---|
| Broker(消息代理) | 存放待执行的任务队列 | 任务"待办清单" |
| Worker | 真正执行任务的进程 | 干活的工人 |
| Beat | 定时调度器,按计划触发任务 | 定时闹钟 |
| Flower | 任务监控面板 | 监控大屏 |
fba 的 Broker 支持 Redis(开发)和 RabbitMQ(生产)两种。
Celery 架构图
三、启动服务
# Worker:执行任务
fba celery worker
# Beat:定时调度
fba celery beat
# Flower:监控面板
fba celery flower初次学习可跳过。注意:如果从未启动过 worker 和 beat,任务结果表缺失,调用任务相关接口会报错,至少启动一次后恢复。
四、定义和调用任务
定义任务
在 backend/app/task/ 目录下定义 Celery 任务:
from celery import Celery
celery_app = Celery(...)
@celery_app.task
def send_email(to: str, content: str):
# 耗时的邮件发送逻辑
...调用任务
调用 .delay() 或 .apply_async() 把任务丢进队列:
send_email.delay(to='user@example.com', content='你好')接口立即返回,邮件在后台由 worker 执行。
任务执行流程
五、定时任务(Beat)
除了手动触发,Celery 还支持定时任务——按计划自动执行(如每天凌晨生成日报)。
通过 Beat 调度器配置,可定义:
- 固定间隔执行(如每 5 分钟)
- 指定时间执行(如每天 3 点)
fba 也内置了
apscheduler(另一个定时任务方案),用于应用内的定时调度,两者可配合使用。
六、Celery vs 应用内定时任务
fba 提供了两种定时能力,简单区分:
| 方案 | 特点 | 适用场景 |
|---|---|---|
| Celery Beat | 独立调度进程,分布式 | 重型、需分布式的定时任务 |
| APScheduler | 应用内调度,轻量 | 简单、单机的定时任务 |
七、常见疑问
Q1:什么操作该用 Celery? 耗时的操作(发邮件、生成报表、批量导入、图片处理),即"接口不需要等它完成"的操作。
Q2:任务失败会怎样? Celery 支持重试机制,可配置 CELERY_TASK_MAX_RETRIES(最大重试次数),失败的任务会自动重试。
Q3:为什么生产环境建议用 RabbitMQ 而不是 Redis 做 Broker? RabbitMQ 在消息可靠性、路由能力上更强,更适合生产环境的高可靠场景;Redis 简单易用,适合开发。
本章小结
关键要点回顾:
- Celery 解决耗时任务的异步执行
- 核心组件:Broker(队列)、Worker(执行)、Beat(定时)、Flower(监控)
- 启动命令:
fba celery worker/beat/flower - 用
.delay()投递任务,接口立即返回 - 定时任务用 Beat 或 APScheduler
下一步: 第 15 章讲时区、国际化等常用中间件和工具,补齐企业级细节。
对应官方文档:
Celery(backend/reference/celery.html)、定时任务(backend/reference/apscheduler.html)