如何让你的FastAPI Celery Worker在压力下优雅起舞?

FastAPI Celery Worker 配置与自动扩展

1. Celery 基础配置

FastAPI 与 Celery 的集成采用生产者-消费者模式,系统架构包含三个核心组件:

graph LR A[FastAPI 应用] -->|任务发布| B[消息代理 Redis/RabbitMQ] B -->|任务接收| C[Celery Worker 节点] C --> D[执行异步任务] D --> E[存储结果到Backend] E --> F[FastAPI返回结果]

该架构实现请求处理与耗时任务的解耦。当用户请求触发生成 PDF 等耗时操作时,FastAPI 将任务信息序列化为 JSON 格式存入消息队列,立即返回任务 ID 而不阻塞主线程。Worker 节点持续监听队列,按先进先出原则处理任务。

在 FastAPI 项目中创建 celery_app.py 文件:

python 复制代码
# celery_app.py
from celery import Celery
from pydantic import BaseModel

CELERY_BROKER_URL = "redis://localhost:6379/0"
CELERY_RESULT_BACKEND = "redis://localhost:6379/1"

app = Celery(
    "fastapi_worker",
    broker=CELERY_BROKER_URL,
    backend=CELERY_RESULT_BACKEND,
    include=["app.tasks"]
)

# 配置任务路由
app.conf.task_routes = {
    "app.tasks.*": {"queue": "main_queue"}
}

class EmailPayload(BaseModel):
    recipient: str
    subject: str
    content: str

版本要求

requirements.txt 复制代码
celery==5.3.6
redis==4.6.0
fastapi==0.109.0
pydantic==2.6.4

2. Worker 启动参数配置

通过命令行参数控制 worker 行为:

bash 复制代码
celery -A app.celery_app worker \
--concurrency=8 \
--loglevel=info \
--queues=main_queue,backup_queue \
--prefetch-multiplier=4 \
--max-tasks-per-child=100

参数说明表

参数 说明 典型值
--concurrency 并行工作进程数 CPU核心数×2
--prefetch-multiplier 预取任务倍数 2-4
--max-tasks-per-child 子进程最大任务数 100-500
--queues 监听的队列名称 main_queue

3. 自动扩展配置

使用动态伸缩策略实现自动扩缩容:

python 复制代码
# celery_autoscale.py
from celery.worker.autoscale import Autoscaler

class SmartAutoscaler(Autoscaler):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.min_workers = 2
        self.max_workers = 10

    def scale(self):
        current_load = self.get_current_load()
        if current_load > 70:  # CPU使用率阈值
            return min(self.max_workers, self.current_workers + 2)
        elif current_load < 30:
            return max(self.min_workers, self.current_workers - 1)
        return self.current_workers

启动命令

bash 复制代码
celery -A app.celery_app worker --autoscale=10,2

4. 容器化部署方案

Docker Compose 部署示例:

yaml 复制代码
# docker-compose.yml
services:
  redis:
    image: redis:7.2-alpine
    ports:
      - "6379:6379"

  worker:
    image: fastapi-celery-worker
    command: celery -A app.celery_app worker --autoscale=10,2
    environment:
      - CELERY_BROKER=redis://redis:6379/0
    deploy:
      mode: replicated
      replicas: 3
      resources:
        limits:
          cpus: '2'
          memory: 1G

5. 监控与日志

配置结构化日志记录:

python 复制代码
# logging_config.py
from celery.utils.log import get_task_logger
import logging

logger = get_task_logger(__name__)

class TaskFormatter(logging.Formatter):
    def format(self, record):
        record.task_id = getattr(record, 'task_id', 'SYSTEM')
        return super().format(record)

formatter = TaskFormatter(
    '[%(asctime)s] [%(task_id)s] [%(levelname)s] %(message)s'
)

课后 Quiz

Q1:如何防止高并发场景下任务堆积? A. 调整 prefetch_multiplier 参数为1 B. 设置多个优先级队列 C. 同时启用自动扩展和队列限流 ✔️

Q2:哪种情况需要增加 max-tasks-per-child 参数? A. 任务内存泄漏时 B. 需要保持长连接时 ✔️ C. CPU使用率过高时

常见报错处理

错误现象 :WorkerLostError: Worker exited prematurely 解决方案

  1. 检查系统ulimit设置:ulimit -n 65535
  2. 增加内存限制:docker run --memory=2g
  3. 添加进程健康检查:
python 复制代码
@app.task(bind=True, max_retries=3)
def critical_task(self):
    try:
        # 业务代码
    except Exception as exc:
        self.retry(exc=exc)

错误现象 :CPendingDeprecationWarning: 消息协议不匹配 解决方案

python 复制代码
app.conf.broker_connection_retry_on_startup = True
app.conf.worker_protocol = 2  # 指定协议版本
相关推荐
Lx35212 分钟前
Hadoop新手必知的10个高效操作技巧
hadoop·后端
豆包MarsCode17 分钟前
TRAE Rules 实践:为项目配置 6A 工作流
trae
写bug写bug28 分钟前
搞懂Spring任务执行器和调度器模型
java·后端·spring
海拥28 分钟前
AI编程实践:使用Trae快速开发“躲避陨石”HTML小游戏
前端·trae
二闹32 分钟前
TCP三次握手的智慧:为什么不是两次或四次?
后端·tcp/ip
熊猫片沃子41 分钟前
Maven在使用过程中的核心知识点总结
java·后端·maven
集成显卡1 小时前
Rust 实战四 | Traui2+Vue3+Rspack 开发桌面应用:通配符掩码计算器
后端·程序员·rust
苏三说技术1 小时前
糟糕,生产环境频繁Full GC,怎么办?
后端
炸薯人1 小时前
每天一个知识点——Java之CAS操作
后端
星你1 小时前
用Spring Boot 搭建自己的 MCP Server
java·后端