什么是Celery,能应用到什么场景

  1. Celery 是什么?适用场景

Celery 是 Python 的一套分布式任务队列(Distributed Task Queue)框架,用于把耗时/异步工作放到后台 Worker 进程/机器上运行。
核心优势:解耦、异步、水平扩展。
常见场景:
• 生成/处理文件、图片/音视频转码、OCR、ML 推理等长耗时任务
• 调用第三方 API、批量爬取/数据管道等IO 密集任务
• 定时/周期性任务(每天/每小时跑批)
• 工作流编排(A→B→并发{C1…Cn}→汇总)

不适用:
• 强实时(毫秒级)或强一致 Exactly-once(Celery 语义是至少一次)
• 一次性小脚本(上 Celery 成本偏高)

  1. 核心架构与术语
    • Client / Producer:发布任务(比如你的 Web/CLI)
    • Broker:消息队列(Redis 或 RabbitMQ 最常见)
    • Worker:消费并执行任务的进程集群
    • Result Backend:存任务结果/状态(Redis、数据库、RPC……)
    • Task:你写的函数,加上 @app.task
    • Queue / Routing:把不同任务路由到不同队列/Worker
    • Canvas:任务组合原语:chain 串行、group 并行、chord 并行后汇总

运行语义:At-least-once(至少一次执行),因此幂等性非常重要。

  1. 最小可运行:5 分钟起步(Redis 版)

3.1 安装

pip install "celery[redis]" redis

3.2 定义应用与任务 celery_app.py

from celery import Celery

app = Celery(
    "demo",
    broker="redis://localhost:6379/0",
    backend="redis://localhost:6379/1",
)
app.conf.update(
    task_serializer="json",
    accept_content=["json"],
    result_serializer="json",
    timezone="Asia/Shanghai",
    enable_utc=True,
)

@app.task(bind=True, autoretry_for=(Exception,), retry_backoff=True, retry_kwargs={"max_retries": 5})
def add(self, x, y):
    return x + y

3.3 启动 Worker

celery -A celery_app.app worker -l info -Q default -n worker@%h -c 4
•	-c 4:并发 4(进程池默认 prefork)
•	-Q default:监听 default 队列

3.4 发送任务

from celery_app import add
r = add.delay(2, 3)         # 异步
print(r.id)                 # 任务ID
print(r.get(timeout=10))    # 同步等待(生产中建议少用)

  1. 与 FastAPI 集成:API 立刻返回,后台跑

4.1 目录结构(示例)

.
├─ app.py              # FastAPI
└─ celery_app.py       # Celery 定义

4.2 app.py

from fastapi import FastAPI, HTTPException
from celery.result import AsyncResult
from celery_app import app as celery, add

api = FastAPI()

@api.post("/tasks/add")
def create_add(x: int, y: int):
    async_result = add.apply_async(args=[x, y], queue="default", countdown=0)
    return {"task_id": async_result.id}

@api.get("/tasks/{task_id}")
def get_status(task_id: str):
    ar = AsyncResult(task_id, app=celery)
    # PENDING / STARTED / RETRY / FAILURE / SUCCESS
    if ar.state == "FAILURE":
        return {"state": ar.state, "error": str(ar.info)}
    return {"state": ar.state, "result": ar.result}

	•	前端调用 /tasks/add 立即得到 task_id(HTTP 200)
	•	之后轮询 /tasks/{task_id} 获取进度/结果
→ 更高级可用 WebSocket/SSE 推送(接入 Celery 事件流)

  1. 定时任务(Celery Beat)

5.1 安装

pip install celery[redis] celery[timezone]

5.2 配置周期表

# celery_app.py 里追加
from celery.schedules import crontab

app.conf.beat_schedule = {
    "every-5-min-clean": {
        "task": "celery_app.cleanup",
        "schedule": crontab(minute="*/5"),
    }
}

@app.task
def cleanup():
    # 清理临时文件/过期数据
    return "ok"

5.3 启动 Beat + Worker

# 终端1
celery -A celery_app.app beat -l info

# 终端2
celery -A celery_app.app worker -l info -Q default

  1. 任务编排(Canvas):chain / group / chord
from celery import chain, group, chord

@app.task
def step1(x): return x + 1

@app.task
def step2(x): return x * 2

@app.task
def merge(results):  # 用于汇总
    return sum(results)
# 串行:((10+1) * 2)
res = chain(step1.s(10), step2.s())()
# 并行 + 汇总:并行算 step2(1..5) → merge(sum)
res2 = chord(group(step2.s(i) for i in range(1, 6)))(merge.s())

使用 chord 需要支持 chord 的后端(Redis/RabbitMQ 均可),并发 fan-out/fan-in 的常用套路。

  1. 可靠性与语义:必须掌握的选项
    • 重试:autoretry_for + retry_backoff / 手工 self.retry(…)
    • 超时:task_time_limit(硬) / task_soft_time_limit(软,可捕获 SoftTimeLimitExceeded)
    • 确认与幂等:
    • task_acks_late=True(执行完成才确认,worker crash 会重投,但要幂等)
    • task_reject_on_worker_lost=True(进程意外退出时拒绝并重排)
    • 数据库/支付类操作必须有幂等键与去重(例如 Redis SETNX/唯一约束)
    • 预取/流控:worker_prefetch_multiplier(默认 4)
    IO 任务可调大;CPU 任务建议 1,避免长任务把队列“吃空”
    • 内存与稳定性:
    • worker_max_tasks_per_child:每个子进程跑 N 个任务后重启,抑制泄漏
    • worker_max_memory_per_child:超过内存阈值重启子进程
    • 结果后端:不取结果就关闭结果(task_ignore_result=True)以减轻 Redis 压力
    • 序列化安全:accept_content=[“json”],不要启用 pickle(安全风险)

  1. 性能调优:CPU vs IO、并发模型与路由
    • 并发模型:默认 prefork(多进程)
    • CPU 密集:prefork + -c≈CPU 核心数(或略高)
    • IO 密集:可考虑 --pool=gevent 或 eventlet(第三方库要兼容)
    • 路由与队列:按业务/优先级拆分队列
# celery_app.py
app.conf.task_routes = {
    "celery_app.heavy_task": {"queue": "cpu"},
    "celery_app.io_task":    {"queue": "io"},
}
# 启动两个 Worker 分别监听
# celery -A celery_app.app worker -Q cpu -c 8
# celery -A celery_app.app worker -Q io  --pool=gevent -c 200

	•	Chunk / Map:大批量小任务 → group+chunks 批处理减少开销
	•	避免大 payload:任务参数只放指针(URL/ID/路径),大文件走对象存储

  1. 运维与监控

9.1 Flower(可视化监控)

pip install flower
celery -A celery_app.app flower --port=5555

可看任务/队列/Worker 状态、失败重试、撤销任务等。

9.2 命令行“指挥手册”

# 查看 Worker
celery -A celery_app.app status
celery -A celery_app.app inspect active
celery -A celery_app.app inspect scheduled
celery -A celery_app.app inspect reserved

# 控制
celery -A celery_app.app control rate_limit celery_app.add 10/m
celery -A celery_app.app control revoke <task_id> --terminate   # 需要 time limit 配合

9.3 度量
• 队列长度、吞吐、失败率、重试率、任务时长分位
• Worker 存活/并发度、重启次数、内存
• Broker(Redis/RabbitMQ)延迟与连接数

可接入 Prometheus Exporter 或自建日志指标。

  1. 部署与生产建议
    • 进程守护:systemd/supervisord/Docker Compose/K8s
    • 多实例:不同队列不同 Worker,方便水平扩展与隔离
    • 配置分离:生产/预发/本地不同 broker/backend/并发/队列名
    • 日志:独立目录、JSON 格式、关联 task_id
    • 升级:Celery 与 Kombu/redis/rabbit 客户端版本一起 pin 住,灰度升级 Worker
    • 时钟:所有节点时钟同步(NTP),避免 ETA/定时偏差
    • 安全:Broker/Backend 加 TLS,凭证不入仓库;参数不携带敏感明文

  1. 常见坑与排错清单
    • “任务消失/重复执行”:检查 acks_late、prefetch_multiplier、Worker 崩溃、幂等性
    • “卡在等待/延迟大”:看队列长度、并发 -c、QPS、Broker 性能/网络
    • “内存涨”:worker_max_tasks_per_child、避免把大对象留在全局、升级库修复泄漏
    • “chord 不回调”:后端不支持或配置错误;确保 result_backend 可用且事件开启
    • “阻塞 Web 线程”:不要在 Web 线程里 result.get(),只返回 task_id 让前端轮询或订阅

  1. 与其他框架对比(简述)
    • Celery:生态成熟、功能全(定时/编排/路由/监控);配置复杂、学习曲线陡
    • Dramatiq / RQ / Huey:上手简单,特性少一些
    • TaskIQ:现代感强、Typing 好;生态与资料量不及 Celery
    • FastAPI BackgroundTasks:同进程轻量异步,不适合长任务/掉电恢复

  1. 速查代码片段(收藏)

任务重试 + 软/硬时限

from celery.exceptions import SoftTimeLimitExceeded

@app.task(bind=True, autoretry_for=(TimeoutError,), retry_backoff=2, retry_kwargs={"max_retries": 3},
          soft_time_limit=60, time_limit=70)
def fetch(self, url):
    try:
        return do_io(url, timeout=10)
    except SoftTimeLimitExceeded:
        # 清理资源
        raise

幂等保护(Redis 锁)

import time
import redis
r = redis.Redis()

@app.task(bind=True, acks_late=True)
def once_task(self, key):
    lock = r.set(f"lock:{key}", "1", nx=True, ex=300)  # 5 分钟
    if not lock:
        return "duplicate"
    try:
        time.sleep(5)
        return "done"
    finally:
        r.delete(f"lock:{key}")

按队列路由

app.conf.task_routes = {"*.thumbnail*": {"queue": "media"}}
# celery -A celery_app.app worker -Q media -c 4

定时(crontab)

from celery.schedules import crontab
app.conf.beat_schedule = {
    "daily-1am": {"task": "app.daily", "schedule": crontab(minute=0, hour=1)}
}

编排(并行后汇总)

res = chord(group(process.s(i) for i in range(100)))(aggregate.s())

一句话收尾

Celery = “把慢事丢后台 + 可编排 + 可横向扩展”。
抓住四根“安全绳”:幂等性、重试/确认、时限、监控;
再用路由/并发模型/预取做性能分层,你就能放心把生产中的“长任务”交给它。

<think>我们被要求解释Celery的定义、基本概念、功能和应用场景。根据提供的引用,我们可以总结如下: 定义: Celery 是一个专注于实时处理和任务调度的分布式任务队列。它是基于Python开发的分布式异步消息任务队列,用于实现任务的异步处理。 功能: 1. 异步任务处理:允许将耗时的任务(如发送邮件、生成报告)放入后台执行,不阻塞主程序。 2. 定时任务调度:支持周期性任务(类似cron)。 3. 分布式处理:可以在多个工作节点上分布任务,实现负载均衡和高可用。 4. 结果存储:支持将任务结果存储到后端(如Redis、RabbitMQ、数据库等)。 应用场景(根据引用[1][2][3]): 1. 高并发后台任务:例如,用户注册后发送欢迎邮件,避免阻塞注册流程。 2. 异步执行耗时操作:如生成缩略图、处理视频转码等。 3. 微服务解耦:通过消息队列实现服务间通信,例如订单服务将生成发票的任务交给Celery Worker处理。 4. 定时任务:如每天凌晨生成统计报表。 不适用场景(引用[3]): 1. 复杂任务编排:需要结合Airflow等工具。 2. 实时性要求极高的任务(微秒级延迟)。 结构图(引用[2]): Celery结构图展示了其核心组件:任务生产者(Producer)、消息中间件(Broker)、工作者(Worker)和结果存储(Result Backend)。生产者发送任务到消息队列,工作者从队列中获取任务并执行,然后将结果存储到结果后端。 代码示例(引用[3]): 一个简单的发送邮件的Celery任务定义和调用。 现在,我们按照要求组织回答:</think>### Celery 的定义与核心概念 **Celery** 是一个专注于**实时任务处理**和**分布式调度**的 Python 异步任务队列框架。它通过消息中间件(如 RabbitMQ/Redis)实现任务的分发与执行,核心目标是**解耦耗时操作**,提升系统吞吐量和响应速度[^1][^2]。 --- ### 核心架构与组件 Celery 采用生产者-消费者模型,包含四个核心组件: 1. **生产者 (Producer)** - 提交异步任务(如 Web 服务接收用户请求后触发任务) ```python # 提交发送邮件任务(非阻塞) send_email.delay(user_id="u123", content="欢迎注册") ``` 2. **消息中间件 (Broker)** - 任务队列存储(常用 RabbitMQ/Redis),确保任务不丢失 - 支持任务优先级、延时执行等特性[^2] 3. **工作者 (Worker)** - 分布式执行单元,从 Broker 拉取任务并执行 ```python # 启动 Worker 进程 celery -A tasks worker --loglevel=info ``` 4. **结果后端 (Result Backend)** - 存储任务执行状态和结果(如 Redis、数据库) ```python result = task.delay(...) print(result.status) # 获取任务状态(PENDING/SUCCESS/FAILURE) ``` --- ### 核心功能 | 功能 | 说明 | 示例场景 | |---------------------|----------------------------------------------------------------------|-----------------------------------| | **异步任务处理** | 将耗时操作移出主流程 | 用户注册后异步发送邮件[^3] | | **定时任务调度** | 类似 cron 的周期性任务 | 每天凌晨生成报表 | | **分布式任务分发** | 任务自动分配到多台 Worker 机器 | 大规模图像处理集群 | | **任务状态追踪** | 实时监控任务进度/结果 | 显示“发票生成中(75%)” | | **错误重试机制** | 任务失败自动重试 | 网络波动时重新调用支付接口 | --- ### 典型应用场景 1. **高并发后台任务** - 用户注册 → 异步发送欢迎邮件(避免阻塞注册流程)[^3] - 电商下单 → 异步生成发票/更新库存 2. **计算密集型操作** ```python @app.task def generate_thumbnail(image_path): # 耗时图像处理(不影响主服务) resize_image(image_path, (800, 600)) return f"{image_path}_thumb.jpg" ``` 3. **微服务解耦** - 订单服务 → 通过消息队列触发「物流调度」任务 - 支付服务 → 异步执行「对账分析」任务 4. **定时批处理** ```python @app.task @periodic_task(run_every=crontab(hour=0, minute=5)) def daily_report(): # 每天 00:05 生成报表 build_sales_report() ``` --- ### 不适用场景 1. **复杂工作流编排** - 需结合 Airflow/Luigi 等调度工具 2. **实时性要求 < 10ms 的任务** - 消息传递存在毫秒级延迟[^3] 3. **强事务一致性操作** - 异步任务难以保证 ACID --- ### 快速入门示例 ```python # tasks.py from celery import Celery # 初始化 Celery(使用 Redis 作为 Broker) app = Celery('tasks', broker='redis://localhost:6379/0') @app.task def send_email(user_email, content): import time time.sleep(3) # 模拟邮件发送耗时 print(f"邮件已发送至 {user_email}: {content}") return True # 调用任务(非阻塞) result = send_email.delay("user@example.com", "欢迎加入!") print(f"任务ID: {result.id}") # 通过ID可查询状态 ``` > **执行流程**: > 1. 启动 Worker:`celery -A tasks worker --loglevel=info` > 2. 生产者调用 `send_email.delay(...)` 提交任务 > 3. Worker 从 Redis 获取任务并执行 > 4. 结果存储至 Redis(需配置 `result_backend`) --- ### 生态扩展 - **工作流编排**:`celery-canvas` 实现任务链/分组 - **监控工具**:`Flower` 提供实时任务仪表盘 - **分布式扩展**:支持 Kubernetes 动态伸缩 Worker ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MonkeyKing.sun

对你有帮助的话,可以打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值