简单来说:Uvicorn 是"单兵作战时的分身",而 Nginx 是"指挥多台坦克的将军"。
在实际生产中,我们通常两个都用。以下是它们的本质区别:
1. 作用范围:单机 vs. 多机
Uvicorn 的"负载均衡":利用多核 CPU
当你在启动 Uvicorn 时使用 --workers 4 参数,它会在同一台服务器上开启 4 个进程。
- 目的 :利用这台机器的多个 CPU 核心。因为 Python 有 GIL 锁(全局解释器锁),一个进程通常只能用一个核。开 4 个 worker 就能让 4 个核同时干活。
- 局限:它跑不出这台机器。如果这台机器的 CPU 满了或者断网了,Uvicorn 也没办法。
Nginx 的负载均衡:利用多台服务器
Nginx 站在多台服务器的前面。
- 目的 :把流量分发到不同的 IP 地址上。
- 优势:它能跨越物理限制。即使服务器 A 冒烟了,Nginx 也能把请求转给服务器 B。
2. 功能侧重点:执行 vs. 管理
| 特性 | Uvicorn (ASGI Server) | Nginx (Reverse Proxy) |
|---|---|---|
| 主要任务 | 解释并执行你的 Python 代码。 | 接收和转发网络流量。 |
| SSL 证书 | 虽然能做,但不专业且性能一般。 | 专家。通常在这里统一处理 HTTPS 加密。 |
| 静态文件 | 性能较差(处理图片、JS 慢)。 | 极快。直接从硬盘读取图片返回,不经过 Python。 |
| 缓冲与超时 | 较弱。 | 极强。能保护后端不被慢速攻击拖垮。 |
| 健康检查 | 不具备查看其他机器状态的能力。 | 具备。能发现哪台后端服务器"挂了"并自动跳过。 |
3. 为什么通常"两个都要用"?(标准架构)
在部署你的 FastAPI 应用时,最专业的做法是套娃式结构:
- 最外层:Nginx
- 负责接收公网的 HTTPS 请求。
- 把请求分发给后端 10 台服务器的内网 IP。
- 中间层:每台服务器里的 Uvicorn (Workers)
- 每台 4核 8GB 的服务器里,运行
uvicorn --workers 4(或者 5-9 个,通常是2 * 核心数 + 1)。 - 这样可以把这台机器的 4 个 CPU 核心全部压榨干净。
- 每台 4核 8GB 的服务器里,运行
- 最内层:你的 FastAPI 代码
- 具体处理业务逻辑。
4. 形象类比
- FastAPI 代码 :是厨师手里的菜谱。
- Uvicorn Workers :是这间厨房里的 4 个厨师。他们共用一个厨房(一台服务器),分头炒菜。
- Nginx :是商场里的前台指引 。他负责把排队的客人们带往 10 家不同的分店(10 台服务器)。
5. 总结
- 如果你只有 1 台服务器 :你只需要用 Uvicorn 的
--workers就可以获得不错的性能。 - 如果你有 多台服务器 :你必须用 Nginx(或其他类似工具)来做入口。
- 最佳实践:Nginx 挡在最前面,后端每台机器上用 Uvicorn 跑多进程。
思考题:如果你在代码里改了一个 Bug,你是需要重启 Nginx,还是需要重启 Uvicorn?
(答案是:只需要重启每台服务器上的 Uvicorn。Nginx 只是个传声筒,它并不关心你的 Python 代码改了什么。)