fastapi 仅负责请求响应,分布式计算由 celery+rabbitmq(broker)+redis(backend)协同实现;二者必须分离部署,且 rabbitmq 专作 broker、redis 专作 backend,不可混用同一 redis 实例或 db,否则引发内存抖动、连接失败与轮询超时。

FastAPI 本身不处理分布式计算,它只负责接收请求、触发任务、返回响应或任务 ID;真正实现高吞吐分布式计算的是 Celery + 消息代理(RabbitMQ)+ 结果后端(Redis)。关键在于:Celery Worker 进程必须与 FastAPI 进程分离部署,且 RabbitMQ 和 Redis 需明确分工——前者只做 Broker,后者只做 Backend。
为什么不能用 Redis 同时当 Broker 和 Backend
Redis 作为 Broker 时,Celery 依赖其 Pub/Sub 或 List 结构投递任务;但当它同时被设为 Backend 时,Celery 会额外写入大量 celery-task-meta- 键,容易引发 Redis 内存抖动、过期键堆积、甚至阻塞主线程。RabbitMQ 在消息可靠性、并发吞吐、死信队列支持上远超 Redis 作为 Broker 的能力,尤其适合生产级高吞吐场景。
常见错误现象:ConnectionRefusedError: Error 111 connecting to localhost:6379(Broker 压力过大断连)、result.get() timeout(Backend 响应慢导致轮询失败)。
- RabbitMQ 配置示例:
broker="amqp://guest:guest@localhost:5672//" - Redis Backend 配置示例:
backend="redis://localhost:6379/1"(务必和 Broker 使用不同 DB) - 不要复用同一 Redis 实例的 DB 0 既做 Broker 又做 Backend
celery -A 启动 Worker 时必须指定 concurrency 和 pool
默认 celery -A myapp worker 启动的是 solo 模式(单线程),根本无法发挥 RabbitMQ 多消费者优势。CPU 密集型任务要用 threads 或 gevent;I/O 密集型(如调用外部 API、数据库查询)才适合 prefork + concurrency=4。
实操建议:
- CPU 密集型:加
--pool=threads --concurrency=8,避免 GIL 锁死 - I/O 密集型:加
--pool=prefork --concurrency=4,配合task_acks_late=True - 永远加上
--loglevel=info,否则失败任务无声消失 - 不要在开发环境用
--autoscale,它依赖 Redis 的心跳机制,在低负载下反而频繁启停进程
FastAPI 路由里调用 delay() 后不能直接 get()
这是最常踩的坑:result = my_task.delay(); return {"id": result.id, "result": result.get()} —— 这会让 FastAPI 请求线程卡住,退化成同步调用,完全失去异步意义。
正确做法是只返回任务 ID,前端轮询或 Webhook 回调获取结果:
- FastAPI 中只做:
task = process_data_task.delay(payload),然后return {"task_id": task.id} - 另起一个
GET /task/{task_id}接口,用AsyncResult(task_id).state和.result查状态 -
AsyncResult必须用和 Worker 完全一致的broker和backendURL 初始化,否则查不到结果 - 别在 FastAPI 中用
result.get(timeout=30),超时会拖垮整个 uvicorn worker 进程
RabbitMQ 的 vhost 和权限配置常被忽略
本地开发可能跳过权限控制,但一旦上生产,RabbitMQ 默认的 guest/guest 账号仅限 localhost 访问,且不能创建 vhost。实际部署必须:
- 创建专用 vhost:
rabbitmqctl add_vhost /fastapi_tasks - 绑定用户权限:
rabbitmqctl set_permissions -p /fastapi_tasks myuser ".*" ".*" ".*" - Celery 配置中 Broker URL 必须带 vhost:
amqp://myuser:mypass@localhost:5672//fastapi_tasks(注意双斜杠) - 漏掉 vhost 或权限会导致 Worker 启动时静默失败,日志只显示
Consumer: Connection refused
分布式计算的吞吐瓶颈往往不在代码,而在 RabbitMQ 队列未设置 x-max-priority、未启用镜像队列、或 Redis Backend 没配 result_expires 导致元数据无限膨胀——这些细节比写任务函数重要得多。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











