Uvicorn、Gunicorn 傻傻分不清?FastAPI 生产部署避坑指南
没有过这种崩溃瞬间 —— 笔记本上uvicorn main:app --reload跑得行云流水接口响应快到飞起。结果兴冲冲部署到服务器并发量刚一上来请求就开始排队然后 502、504 哗啦啦地来用户群里瞬间炸锅。别问我怎么知道的那种滋味真不想你再尝一遍。所以今天这篇我打算把Uvicorn、Gunicorn这些名字绕口的家伙用你最听得懂的方式盘一遍再给你一套拿来就能用的部署配置。我是爱折腾的一名程序媛喜欢研究全栈开发的各种实践热爱分享踩坑后的收获与思考也享受用代码写出各种实用小工具解决问题的快乐。如果你也在技术这条路上向前走关注我愿我们能彼此陪伴一起成为更好的自己 本文能帮你解决什么 搞清楚 Uvicorn、Gunicorn、WSGI、ASGI 到底谁是谁的谁 知道什么时候用uvicorn --workers什么时候必须上 Gunicorn 拿到生产级 Gunicorn Uvicorn 的配置样板 避开端口冲突、超时、僵尸进程等常见大坑 学会不同环境开发、Docker、Linux 生产的部署套路 核心原理别把“饭店伙计”当成“饭店老板”很多人刚接触部署以为uvicorn就是一个完整的 Web Server其实它更像一个跑得很快的伙计能端菜处理请求但不会管理后厨的人手。咱们打个比方你的 FastAPI 应用是一家网红餐厅Uvicorn是手脚麻利的服务员接单上菜特别快尤其是对需要等一会的菜异步请求它能先去招呼别桌不会傻站着。Gunicorn是店长它自己不端盘子但它管着一群服务员规定谁干活、干多少活、干累了换班、出了错重启。Nginx是门口的大堂经理负责迎客、分流、挡掉捣乱的人。那 WSGI 和 ASGI 呢就是服务员和后厨的沟通协议。 WSGI 是同步的一次只端一个菜。 ASGI 是异步的适合同时处理好几桌的点单FastAPI 天生就讲 ASGI 语。好现在你肯定想问那 Uvicorn 自己不是也有--workers参数吗直接用不就行了接下来重点来了。⚡ 实战对比直接裸奔 vs 工头带队 方案一直接uvicorn --workers 4确实Uvicorn 支持多 worker但这个“多”是靠它自己 fork 出来的没有 Gunicorn 那么老练。实际跑起来你会发现 某个 worker 悄悄死掉它不一定能拉起来。 内存占用管理比较糙。 信号处理和优雅关机偶尔就闹脾气。这里有一点要特别注意如果你在 Windows 上开发--workers根本不能用你只能老老实实开多个进程用端口转发巨麻烦。所以 Windows 上只建议跑单 worker 做调试。️ 方案二Gunicorn UvicornWorker生产首选这才是正经的生产之道。用 Gunicorn 来管理多个 Uvicorn worker 进程每个 worker 依然使用 ASGI 协议稳得一批。命令长这样gunicorn main:app -w 4 -k uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000-w 4开 4 个 worker 进程。-k uvicorn.workers.UvicornWorker指定干活的是 Uvicorn 的 worker 类而不是默认的同步 WSGI worker。--bind监听所有网络接口的 8000 端口。根据我以往的经验worker 数设为 CPU 核心数 × 2 1 是个比较稳的开局后期看负载再调。一味开多上下文切换反而会拖慢整体。再说个容易翻车的点超时时间。默认 Gunicorn 的 worker 超时只有 30 秒。如果你的某个接口处理慢比如生成报表要 1 分钟那 Gunicorn 会直接杀掉 worker用户那头就是 502。务必在启动时加上--timeout 120或者更合适的值。 不同环境的落地姿势 开发环境追求快和热重载单进程 Uvicorn 就是最佳答案uvicorn main:app --reload --host 0.0.0.0 --port 8000千万别在--reload时加--workers你会收获一堆僵尸进程和莫名其妙的文件监控错误。 Docker 单容器部署很多人在这里踩坑容器里起了 Gunicorn前面要不要再套 Nginx如果单机跑且只在容器内用一个进程Gunicorn 足够。但更推荐 Nginx Gunicorn 分开用docker-compose。Gunicorn 的--bind 0.0.0.0:8000后面让 Nginx 做反向代理处理静态文件和限流。一个小而美的Dockerfile片段CMD [gunicorn, main:app, -w, 4, -k, uvicorn.workers.UvicornWorker, --bind, 0.0.0.0:8000] Linux 生产物理机配合systemd或supervisor做进程守护让 Gunicorn 自己做个乖孩子。把上面那条命令写进启动脚本让系统帮你盯着挂了自动拉起来。 常见翻车现场及抢救启动报端口占用大概率是上个进程没死干净lsof -i :8000查出来kill掉。静态文件 404Gunicorn/Uvicorn 就别伺候静态文件了丢给 Nginx性能能翻好几倍。WebSocket 连不上如果前面套了 Nginx记得升级proxy_set_header Upgrade和Connection upgrade配置不然 WebSocket 握手直接断。日志里全是 worker timeout检查你是不是有个接口偷偷同步调了个耗时的第三方库把代码改成async搭配异步请求库。 最后啰嗦一句工具的选择上我认为顺手的才是最好的Uvicorn Gunicorn 这对组合我认为是最稳的。你不用迷信它们但一定要理解背后“异步处理 进程管理”的思想这样换成 Hypercorn、Daphne 也能一通百通。