Celery学习记录

7 阅读4分钟

Celery 超详细完整版讲解(原理 + 架构 + 角色 + 流程 + 用法 + 底层逻辑)

一、Celery 官方定位

Celery 是基于 Python 的分布式异步任务队列 + 定时任务框架。核心作用:把耗时、阻塞、非即时返回的业务,从主应用(FastAPI/Django/Flask)剥离,丢到后台独立进程异步执行,不阻塞主接口响应

支持:

  • 异步延时任务
  • 定时周期任务
  • 分布式多机器部署
  • 任务重试、失败回调、任务结果存储、任务限流、队列隔离

二、核心三大核心组件(必记)

1. Broker 消息中间人

作用:任务的中转站、消息队列仓库。主程序把任务发往 Broker,Worker 从 Broker 取任务执行。常用:

  • Redis:部署简单、中小型项目首选
  • RabbitMQ:可靠性更高、适合企业级、消息不丢

类比:快递驿站,先把包裹放驿站,快递员再来取。

2. Worker 工作进程

作用:真正执行任务的后台进程 / 线程。你之前写的 start_celery_worker() 就是手动启动 Worker。特点:

  • 可以启动多个 Worker、多并发 concurrency
  • 可以分布在多台服务器,做分布式任务处理
  • 支持进程池 / 线程池 /gevent 协程池

类比:快递派送员,从驿站拿包裹去送货。

3. Backend 结果后端(可选)

作用:存储任务执行结果、返回值、状态(成功 / 失败 / 耗时)。常用:Redis、MySQL、MongoDB、RabbitMQ。如果不需要获取任务返回结果,可以不用配置 Backend

类比:快递签收记录,存起来方便后续查询。


三、完整工作执行流程

  1. 业务代码(FastAPI 接口 / 普通函数)调用 task.delay() / task.apply_async() 推送任务
  2. Celery 把任务函数名、参数、执行时间序列化
  3. 推入 Broker(Redis/RabbitMQ)队列
  4. 后台 Worker 一直轮询监听 Broker
  5. Worker 拿到任务,独立进程 / 线程执行
  6. 执行完,可选把结果存入 Backend
  7. 主程序完全不阻塞,立刻返回响应

流程图简化:

plaintext

业务代码 → 发送任务 → Broker队列 → Worker消费执行 → (结果存入Backend)

四、能解决什么问题(业务场景)

  1. 接口响应慢发邮件、发短信、推送消息,不走主接口,异步跑。
  2. 耗时计算生成 Excel/Word 报表、数据统计、大数据清洗。
  3. 文件处理图片压缩、视频转码、PDF 解析、文档分块。
  4. 定时任务每天凌晨备份数据、定时账单生成、定时爬虫、定时清理日志。
  5. 解耦削峰高并发时把任务丢队列,慢慢消费,不会压垮主服务。
  6. 分布式任务多台机器同时跑 Worker,分担任务压力。

五、Celery 核心概念详解

1. Task 任务

@app.task 装饰的普通 Python 函数,就是一个 Celery 任务。可以配置:重试次数、超时时间、队列路由、优先级。

2. 队列 Queue

可以划分多个队列:

  • default 默认队列
  • email 邮件队列
  • report 报表队列不同 Worker 只监听指定队列,任务隔离互不干扰

3. 并发 Concurrency

你代码里 settings.celery_concurrency 就是并发数:设置 Worker 同时能跑多少个任务,一般设为 CPU 核心数 或 2~4 倍。

4. 任务调用方式

  • task.delay(arg1, arg2):最简调用
  • task.apply_async(args=[arg1], countdown=5):延迟 5 秒执行

5. 定时任务 Beat

Celery Beat 是定时调度器,类似 Linux crontab。每秒轮询,到时间就把任务丢进 Broker,由 Worker 执行。


六、和普通多线程 / 多进程的区别

表格

方式缺点Celery 优势
原生多线程只能本机、重启任务丢失、无持久化、不能分布式任务持久化、支持多机器、重启不丢任务、可重试、可定时、可队列隔离
原生多进程配置麻烦、无任务管理、看不到任务状态有完善监控、状态追踪、结果存储、自动重试

结论:简单临时任务用多线程;企业级、持久化、分布式、定时任务 必须用 Celery


七、项目结构标准写法

plaintext

project/
├── tasks/
│   ├── __init__.py
│   ├── celery_app.py   # 初始化Celery实例
│   ├── task_email.py   # 邮件任务
│   └── task_report.py  # 报表任务
└── start_worker.py     # 你写的启动Worker函数

celery_app.py 核心:初始化 app、配置 broker、backend、导入所有任务。


八、你那段代码的底层含义

python

运行

def start_celery_worker():
    from tasks.celery_app import app as celery_app
    worker_cli = worker.worker(app=celery_app)
    worker_cli.run(loglevel="info", concurrency=settings.celery_concurrency)

作用:

  1. 导入项目初始化好的 Celery app 实例
  2. 编程式创建 Worker 实例
  3. 启动 Worker,指定日志级别、并发数
  4. 后台一直监听 Broker 队列,有任务就自动执行

等价命令行:

bash

运行

celery -A tasks.celery_app worker -l info -c 并发数

适合代码内一键启动、Windows 部署、Docker 启动脚本。


九、关键优缺点总结

优点

  • 解耦主业务,接口秒响应
  • 任务持久化,重启不丢失
  • 支持分布式、多队列、定时任务
  • 自带重试、超时、失败回调
  • 完美适配 Django/FastAPI/Flask

缺点

  • 依赖 Broker(必须 Redis/RabbitMQ)
  • 多了中间件,部署稍复杂
  • 小型简单项目有点重