惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

J
Java Code Geeks
月光博客
月光博客
aimingoo的专栏
aimingoo的专栏
Google DeepMind News
Google DeepMind News
Recent Announcements
Recent Announcements
MyScale Blog
MyScale Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
S
SegmentFault 最新的问题
Hugging Face - Blog
Hugging Face - Blog
Martin Fowler
Martin Fowler
WordPress大学
WordPress大学
F
Fortinet All Blogs
小众软件
小众软件
D
Docker
U
Unit 42
博客园 - 聂微东
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
爱范儿
爱范儿
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
IT之家
IT之家
云风的 BLOG
云风的 BLOG
博客园 - 司徒正美
有赞技术团队
有赞技术团队
腾讯CDC

博客园 - 一名程序媛呀

Anki插件开发必知必会:钩子函数与右键菜单定制 httpx 传参总报错?这次把 GET、POST、文件上传到响应处理的坑给你一次填平 从卡顿到丝滑:FastAPI 调用外部 API 的正确姿势(httpx 实战) 还在 XHR、Fetch 和 Axios 之间纠结?我踩过的坑,希望你一个都不用碰到 你的REST接口还在“过度投喂”数据吗?——FastAPI + GraphQL实战避坑指南 Termux里的二进制和脚本,到底怎么运行才不踩坑?Termux-service 保活妙招! 刚部署的 LibreTranslate 频频翻车?我掏出了 20 年前的 StarDict 词典,用 FastAPI 搭了个本地词典翻译 API 别再用网页翻译看源码了!你的私人翻译神器LibreTranslate,部署避坑指南来了 掏出手机就能搭个 WebDAV 同步服务器?这操作有点香 别只盯着GitBook了!这个文档神器让你的笔记秒变网站 写爬虫时用了代理还被封?Python 代理的那些隐藏坑,我替你踩明白了 FastAPI 身份验证总踩坑?这份 FastAPI Users “避坑指南”请收好 旧手机别扔!用 Termux 搭个私人云盘,比网盘香多了 你的FastAPI又在服务器上“跑不起来”了?来,今天咱把打包这件事彻底聊透 写页面时别再把 Element Plus 整个搬进来啦!Vue3按需加载的坑我帮你踩平了 前端包管理咋选?我从npm叛逃到pnpm的血泪史(附避坑指南) 聊聊 fetch 使用中我踩过的那些坑和正确打开方式 FastApiAdmin 后端接口开发好了,前端管理界面怎么调用与显示? 给 FastApiAdmin 加个“会议纪要”模块,我把后端二次开发的坑踩了个遍 我用了FastApiAdmin后,连夜把踩过的坑都整理出来了 告别 Typora 后的新欢:我把所有笔记迁移到了 Obsidian 这个“第二大脑” 你的Agent API还在裸奔?从认证到沙箱,我用FastAPI搭了几道防线 让 FastAPI Agent 思考不阻塞:手把手教你实现异步任务与后台处理方案 让FastAPI Agent真正记住你:聊聊会话记忆与持久化存储的落地实践 FastAPI Agent 函数调用实战:我让 AI 学会了“自己动手查天气“ 初探:用 FastAPI 搭建你的第一个 AI Agent 接口 FastAPI 少有人提的实用技巧:把 Depends 依赖提到路由层,代码少写60% FastAPI 生产环境静态文件完全指南:从 /favicon.ico 404 到 HSTS 混合内容,一次全根治 用了loguru我才明白,Python日志还能这么写 FastAPI 后台任务:BackgroundTasks 的使用场景与注意事项
Uvicorn、Gunicorn 傻傻分不清?FastAPI 生产部署避坑指南
一名程序媛呀 · 2026-06-25 · via 博客园 - 一名程序媛呀

摘要:你是不是也遇到过 FastAPI 应用一上量就卡死、502 频发?这篇来自程序媛老友的经验之谈,不讲天书,只给你最落地的 ASGI/WSGI 服务器选型指南、配置参数详解和 Docker、Linux 部署实例。哪怕你只懂一点后端,跟着做也能搞出一个稳建的生产环境。

🎯 开头就是暴击:为什么我的 FastAPI 一上生产就跪?

你有没有过这种崩溃瞬间 —— 笔记本上 uvicorn main:app --reload 跑得行云流水,接口响应快到飞起。
结果兴冲冲部署到服务器,并发量刚一上来,请求就开始排队,然后 502、504 哗啦啦地来,用户群里瞬间炸锅。

别问我怎么知道的,那种滋味,真不想你再尝一遍。

所以今天这篇,我打算把 UvicornGunicorn 这些名字绕口的家伙,用你最听得懂的方式盘一遍,再给你一套拿来就能用的部署配置。

👩‍💻我是爱折腾的一名程序媛,喜欢研究全栈开发的各种实践,热爱分享踩坑后的收获与思考,也享受用代码写出各种实用小工具解决问题的快乐。

如果你也在技术这条路上向前走,关注我,愿我们能彼此陪伴,一起成为更好的自己 🌱

📌 本文能帮你解决什么

🔹 搞清楚 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 生产物理机

配合 systemdsupervisor 做进程守护,让 Gunicorn 自己做个乖孩子。

把上面那条命令写进启动脚本,让系统帮你盯着,挂了自动拉起来。

🚨 常见翻车现场及抢救

🔹 启动报端口占用
大概率是上个进程没死干净,lsof -i :8000 查出来 kill 掉。

🔹 静态文件 404
Gunicorn/Uvicorn 就别伺候静态文件了,丢给 Nginx,性能能翻好几倍。

🔹 WebSocket 连不上
如果前面套了 Nginx,记得升级 proxy_set_header UpgradeConnection "upgrade" 配置,不然 WebSocket 握手直接断。

🔹 日志里全是 worker timeout
检查你是不是有个接口偷偷同步调了个耗时的第三方库,把代码改成 async 搭配异步请求库。

💬 最后啰嗦一句

工具的选择上,我认为顺手的才是最好的!Uvicorn + Gunicorn 这对组合我认为是最稳的。
你不用迷信它们,但一定要理解背后“异步处理 + 进程管理”的思想,这样换成 Hypercorn、Daphne 也能一通百通。


把这篇文章保存起来吧,下次半夜被报警电话吵醒的时候,说不定靠这里面的某一句话就能多睡一小时。
如果觉得有用,点赞收藏加个关注,转发给那个还在和 502 死磕的朋友,咱们的技术路,一起少掉两根头发 🎯。