打开网易新闻 查看精彩图片

你的FastAPI应用在本地跑得像跑车,上线后却变成拖拉机。这不是框架的锅,是部署姿势错了。

一位有10年Python经验的工程师在Medium上复盘了他亲手修复的生产事故。7个错误,个个致命,却天天有人踩。本文用数据冲击开场——某团队因第3个错误,API宕机4小时,直接损失6位数。

错误1:把Uvicorn当生产服务器用

错误1:把Uvicorn当生产服务器用

本地开发用uvicorn main:app --host 0.0.0.0 --port 8000,上线照抄这套配置,等于给自己埋雷。

Uvicorn单进程单线程,流量一涨就卡死。一个请求崩溃,整个服务陪葬。生产环境必须用Gunicorn+Uvicorn组合:Gunicorn管多进程,Uvicorn管异步事件循环。

正确配置长这样:

Gunicorn启动多个worker进程,每个worker内部跑Uvicorn的异步循环。流量分摊到多个进程,单点故障被隔离。

worker数量别拍脑袋。公式是(2 × CPU核心数) + 1,留一个核心给系统和其他任务。

错误2:异步代码里塞了同步操作

错误2:异步代码里塞了同步操作

FastAPI的async def不是魔法。你在异步函数里调time.sleep(5)或查数据库用同步驱动,整个事件循环被卡住。

所有并发请求排队等这一个操作完成。100个并发进来,变成串行执行,async的优势归零。

排查方法:用asyncio.run(main())跑压力测试,观察是否出现"假并发"。数据库换asyncpgsqlalchemy的异步模式,文件IO用aiofiles,HTTP请求用httpx

这位工程师的原话:「我见过一个团队把Pandas的DataFrame操作全写在async函数里,CPU密集型任务占满GIL,'异步'了个寂寞。」

错误3:依赖注入不做生命周期管理

错误3:依赖注入不做生命周期管理

某厂API崩4小时的元凶找到了:数据库连接池在依赖注入里反复创建,没做关闭处理。

FastAPI的Depends默认每次请求都实例化依赖。如果你的依赖打开数据库连接、Redis连接、文件句柄,请求一多资源耗尽。

正确姿势是用yield做上下文管理:

依赖函数用yield返回资源,FastAPI会在请求结束后执行yield之后的清理代码。连接池复用、句柄关闭、事务回滚,全在这里处理。

更隐蔽的坑:全局单例依赖。用lru_cache或模块级变量缓存依赖实例,但别忘了测试环境要能重置,否则单测互相污染。

错误4:Pydantic模型当万能胶

错误4:Pydantic模型当万能胶

FastAPI自动把请求体转成Pydantic模型,方便是方便,滥用就出事。

大JSON嵌套5层以上,Pydantic的验证开销指数级增长。某团队接收第三方回调,10MB的JSON数组,验证耗时8秒,超时全报500。

解法分两层:输入层用BaseModel做基础校验,业务层再用专用模型。或者直接用Request对象拿原始body,手动解析关键字段。

另一个陷阱:模型字段全用Optional。业务必填的字段在模型里标可选,校验漏过去,数据库插入时才报错。Pydantic的Field(..., min_length=1)Optional[str]更安全。

错误5:日志配置复制粘贴

错误5:日志配置复制粘贴

开发环境的日志配置直接扔生产,要么淹没在INFO里找不到ERROR,要么DEBUG日志把磁盘撑爆。

结构化日志是底线。JSON格式、统一字段名、可追踪的request_id,ELK或Loki才能解析。这位工程师推荐structlog+标准库logging的组合。

关键配置:UVICORN_ACCESS_LOG设成False,用自定义中间件打访问日志,才能注入用户ID、链路追踪ID。异常日志必须包含堆栈和请求上下文,否则线上报错等于白报。

错误6:健康检查走过场

错误6:健康检查走过场

Kubernetes的livenessProbe配个/health返回200就完事?数据库挂了、Redis断了、队列堵了,健康检查照样通过,流量继续往死服务上打。

深度健康检查要验依赖:数据库SELECT 1、Redis PING、关键外部服务探活。但别做太重,探针本身拖垮服务。

分层设计:/health/live只验进程存活,/health/ready验依赖就绪。启动时先ready再接收流量,关闭时先unready再停服务,零停机部署靠这个。

错误7:性能测试只在本地跑

错误7:性能测试只在本地跑

Locust单机压1000并发,上线后10000并发崩了。为什么?本地没网络延迟、没数据库竞争、没真实的数据分布。

生产级压测要模拟:跨可用区网络、慢查询数据库、缓存穿透、异常请求比例。用k6或Artillery,从外部网络打流量,观察P99延迟和错误率拐点。

这位工程师的收尾建议:「监控比测试更重要。延迟直方图、错误率、饱和度、流量,四个黄金指标配齐告警。等用户来投诉就晚了。」

你的FastAPI应用现在用的是单Uvicorn还是Gunicorn+Uvicorn?最近一次生产事故,根因是代码问题还是部署配置?