You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FastAPI+Uvicorn+Celery生产环境后台任务调度,p99响应时间过高排查

FastAPI+Celery高并发下p99响应时间过高排查方案

我在8vCPU的EC2实例上部署FastAPI+Uvicorn服务,配置4个Uvicorn worker和4个Celery worker。服务逻辑为:POST接口接收数据后,调用Celery调度后台CPU密集型任务,立即返回响应。但每秒40并发请求时,p99响应时间高达600ms,远未达到预期的两位数水平。已尝试FastAPI内置BackgroundTasks,因CPU密集型任务不适用而放弃,现需排查性能瓶颈。

相关代码

from fastapi import FastAPI
from celery import Celery  # 注:原代码拼写错误修正为celery

celery_app = Celery("tasks", broker="redis://localhost:6379/0", backend="redis://localhost:6379/0")

app = FastAPI(lifespan=lifespan)

def generate_model_score(request_data):
   # CPU密集型ML模型评分计算逻辑
   pass

@app.post("/predict/")
async def sample_fn(request_data: dict):
    
    if total_transactions == 0:
        logger.info("user doesnt have any data")
        return default_response(request_data['userId'])
    
    generate_model_score.delay(request_data)
    logger.debug("end of predict")

    # 立即返回假数据
    return default_response(request_data['userId'])

1. Redis性能瓶颈排查

  • 当前Redis与服务、Celery同部署在EC2实例,CPU密集型任务会与Redis抢占CPU资源,导致delay()调用时Redis响应缓慢。执行redis-cli INFO stats查看instantaneous_ops_per_sec、latency指标,确认是否存在请求排队情况。
  • 可尝试将Redis单独部署到专用实例,或优化Redis配置:调大内存分配避免swap使用,开启tcp-keepalive减少连接开销。

2. Uvicorn worker配置优化

  • 8vCPU实例配4个Uvicorn worker数量可能偏低。CPU绑定服务通常推荐worker数为核心数+1,但需考虑Celery worker的CPU占用。试试将Uvicorn worker调整到6个,Celery worker减至2个,平衡CPU资源分配。
  • 确认Uvicorn通过--workers参数启动,且使用uvicorn.workers.UvicornWorker异步worker,避免同步worker阻塞事件循环。

3. 接口内同步阻塞逻辑检查

  • 检查total_transactions的计算是否为同步阻塞操作?如果每次请求都需查询数据库或其他存储,会直接拖慢响应速度。给这段代码添加日志打点,统计执行耗时。
  • 排查default_response函数是否存在同步IO或计算逻辑,导致返回响应前的阻塞。

4. Celery worker的CPU抢占问题

  • 4个Celery worker均为CPU密集型任务,在8vCPU实例上会占用大量CPU资源,挤压Uvicorn worker的运行空间(解析请求、提交任务、返回响应均需CPU)。用htop实时查看CPU使用率,若Celery长期占满CPU,需调整配置。
  • 可减少Celery worker数量至2-3个,给Uvicorn留足CPU资源;或给Celery worker设置CPU使用率限制。

5. 请求序列化与解析开销

  • FastAPI接收request_data: dict时,若请求体较大,JSON解析会消耗较多CPU。检查请求体大小,或替换为Pydantic模型,FastAPI对Pydantic的解析优化更充分。
  • generate_model_score.delay(request_data)会将数据序列化存入Redis,数据量大时序列化和写入耗时会增加。试试用msgpack替代JSON序列化,或压缩数据后再存储。

6. EC2实例资源瓶颈排查

  • 通过CloudWatch查看实例的CPU使用率、内存、网络指标:CPU长期接近100%说明资源不足;内存不足导致swap频繁也会严重拖慢性能。
  • 确认实例开启了enhanced networking,网络性能不足会影响Redis的读写速度。

内容的提问来源于stack exchange,提问作者Punit Vara

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 07:08:20