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
相关产品推荐
相关产品推荐

