FastAPI Celery Worker 配置与自动扩展
1. Celery 基础配置
FastAPI 与 Celery 的集成采用生产者-消费者模式,系统架构包含三个核心组件:
任务发布
任务接收
FastAPI 应用
消息代理 Redis/RabbitMQ
Celery Worker 节点
执行异步任务
存储结果到Backend
FastAPI返回结果
该架构实现请求处理与耗时任务的解耦。当用户请求触发生成 PDF 等耗时操作时,FastAPI 将任务信息序列化为 JSON 格式存入消息队列,立即返回任务 ID 而不阻塞主线程。Worker 节点持续监听队列,按先进先出原则处理任务。
在 FastAPI 项目中创建 celery_app.py 文件:
# 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
版本要求
celery==5.3.6 redis==4.6.0 fastapi==0.109.0 pydantic==2.6.4
2. Worker 启动参数配置
通过命令行参数控制 worker 行为:
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. 自动扩展配置
使用动态伸缩策略实现自动扩缩容:
# 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
启动命令
celery -A app.celery_app worker --autoscale=10,2
4. 容器化部署方案
Docker Compose 部署示例:
# 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. 监控与日志
配置结构化日志记录:
# 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 解决方案:
- 检查系统ulimit设置:
ulimit -n 65535
- 增加内存限制:
docker run --memory=2g
- 添加进程健康检查:
@app.task(bind=True, max_retries=3) def critical_task(self): try: # 业务代码 except Exception as exc: self.retry(exc=exc)
错误现象:CPendingDeprecationWarning: 消息协议不匹配 解决方案:
app.conf.broker_connection_retry_on_startup = True app.conf.worker_protocol = 2 # 指定协议版本