FastAPI 部署核心概念全解:HTTPS、进程、启动、重启与复制的底层原理
【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi
在把FastAPI应用(或任何类型的 Web API)真正上线时,真正决定成败的往往不是框架 API 的用法,而是一组贯穿始终的部署概念:安全(HTTPS)、开机自启、崩溃重启、多进程复制(Replication)、内存占用以及启动前的准备步骤。本文是 FastAPI 官方部署指南(docs/hi/docs/deployment/concepts.md)的深入解读,将逐条拆解这些概念及其对生产环境的影响,并结合当前仓库的源码与相邻章节,帮助你建立一套通用的部署直觉——即使未来出现全新的部署平台,也能依据这套概念快速评估与设计出最适合自己的方案。
无论你最终选择裸机 + Systemd、Docker、Kubernetes 还是云厂商托管服务,底层考虑的始终是同一批核心变量。阅读完本文,你将能够:说清 Program 与 Process 的本质区别、解释为什么 HTTPS 必须由应用之外的组件终结、理解 worker 数量与内存的线性关系、并知道数据库迁移这类"启动前步骤"为什么只能由单个进程执行。
安全:HTTPS 由谁负责
在部署讨论中首先要认清的事实是:HTTPS 加密通常不是由你的应用服务器(例如 Uvicorn)直接提供的,而是由一个位于应用服务器外部的组件完成——即TLS Termination Proxy(TLS 终止代理)。
同时,必须有一个角色负责HTTPS 证书的自动续期(renew),它可以是 TLS 代理本身,也可以是另一个独立组件。
可充当 TLS Termination Proxy 的工具
官方文档给出的典型工具清单如下:
| 工具 | 证书续期方式 |
|---|---|
| Traefik | 自动处理证书续期 ✨ |
| Caddy | 自动处理证书续期 ✨ |
| Nginx | 需要 Certbot 等外部组件配合续期 |
| HAProxy | 需要 Certbot 等外部组件配合续期 |
| Kubernetes + Ingress Controller(如 Nginx) | 需要 cert-manager 等外部组件配合续期 |
| 云厂商托管服务 | 由云服务内部处理(见下文) |
另一种务实选择是使用云服务:由云厂商完成包括 HTTPS 配置在内的更多工作,代价可能是功能受限或费用更高,但你不再需要自行搭建 TLS Termination Proxy。具体的落地示例将在 HTTPS 章节 与后续部署章节中给出。
Program 与 Process:两个易混淆的基础概念
后续讨论会大量出现"进程(process)",因此先厘清它与"程序(program)"的差异至关重要。
什么是 Program
"程序"一词在日常中泛指多种事物:
- 你编写的代码,也就是Python 文件;
- 能被操作系统执行的文件,例如
python、python.exe或uvicorn; - 某个程序正运行在操作系统上、占用 CPU 并把数据放进内存时的状态——这种情况也常被称为进程。
什么是 Process
"进程"的用法则要精确得多,仅指在操作系统中正在运行的那个东西:
- 它既不指文件、也不指代码,而是特指被操作系统执行和管理的实体;
- 任何程序、任何代码,只有在其被执行(即有进程在运行)时才能做事情;
- 进程可以被你或操作系统终止(terminate / kill),一旦终止它便无法再做任何事;
- 电脑上每个运行中的应用背后都有一个进程,开机期间通常同时运行着大量进程;
- 同一个程序可以同时存在多个进程。
打开操作系统里的"任务管理器"或"系统监视器"就能直观看到这一现象——比如同一个浏览器程序(Firefox、Chrome、Edge 等)往往每个标签页一个进程,外加若干辅助进程。这与 FastAPI 部署中"一个程序、多个 worker 进程"的模式本质相同。
开机自启(Running on Startup)
绝大多数场景下,你希望 Web API始终运行、永不中断,让客户端随时可以访问——除非你有特殊理由让它只在某些情况下运行。
远程服务器上的朴素做法
在远程服务器(云服务器、虚拟机等)上,最省事的方式就是像本地开发一样手动执行fastapi run(该命令底层即 Uvicorn,见 fastapi/cli.py,它要求安装fastapi[standard])或等价命令。
这在开发阶段没问题,但存在致命隐患:
- 一旦你与服务器的 SSH 连接断开,运行中的进程很可能会随之死掉;
- 如果服务器因更新、云厂商迁移等原因重启,你可能毫不知情,自然也不会手动重启进程——于是你的 API 就那样一直"死"着。
让程序自动随系统启动
因此,你通常需要一个独立的外部程序来保证应用在系统启动时自动运行;很多时候它还负责拉起数据库等其他组件。典型工具有:
- Docker
- Kubernetes
- Docker Compose
- Docker in Swarm Mode
- Systemd
- Supervisor
- 云厂商服务内部托管
- 其他…
后续章节会给出这些工具的具体配置示例。
重启(Restarts)
保证应用开机自启只是第一步,你还需要保证它在失败后能被重启。
我们都会犯错
作为人类,我们时刻都在犯错,软件中几乎总在不同角落潜伏着 bug,而开发者修复旧 bug、开发新功能时还可能引入新 bug——因此系统必须具备从故障中恢复的能力。
小错误:由 FastAPI 自动隔离
用 FastAPI 构建 Web API 时,如果业务代码抛出错误,FastAPI通常会把影响限制在触发该错误的那一次请求内:该请求的客户端会收到500 Internal Server Error,但应用本身不会整体崩溃,而是继续为后续请求服务。相关处理机制可参考 docs_src/handling_errors 下的示例与 tests/test_exception_handlers.py 等测试。这正是"应用级进程保持存活"的基础防线。
大错误:整个进程崩溃
但仍存在某些代码会把整个应用拖垮,连 Uvicorn 与 Python 一并崩溃。此时你依然不希望应用因为某处的一个错误就整体停摆——至少那些未损坏的路径操作(path operations)应当继续可用。
崩溃之后怎么办
当真正严重的错误把运行中的进程搞崩溃后,你需要一个外部组件负责把进程重启(至少几次)。原因很朴素:到这一步,运行 Uvicorn 和 Python 的应用自身已经崩溃,应用内任何代码都无能为力,只有进程之外的"看护者"能把它拉起来。
官方文档也给出了一条实用忠告:如果整个应用一启动就立即崩溃,无限重启没有意义——这种问题通常会在开发阶段或刚部署时就被发现。真正需要"崩溃后重启"机制的,是那些未来在特定场景下可能偶发崩溃、但重启仍有价值的情况。
负责自动重启的工具
大多数情况下,负责开机自启的工具同时就是负责自动重启的工具,例如:
- Docker
- Kubernetes
- Docker Compose
- Docker in Swarm Mode
- Systemd
- Supervisor
- 云厂商服务内部托管
- 其他…
复制:多进程与内存(Replication)
对 FastAPI 应用而言,用运行 Uvicorn 的fastapi命令把它以单个进程跑起来,就已经能并发服务多个客户端。但很多场景下你会希望同时运行多个 worker 进程。
什么时候需要多个 Worker
当单进程能处理的客户端数量达到上限(例如虚拟机本身不大),而服务器 CPU 又拥有多核时,你就可以让同一应用的多个进程同时运行,并把请求分发到它们之间。同一 API 程序的多个进程通常被称作workers。
Worker 进程与端口的关系
回顾 HTTPS 章节中提到的约束:一台服务器上,一个 IP 与端口的组合只能被一个进程监听——这一点在多进程下依然成立。
因此,要同时运行多个进程,必须存在一个监听端口的进程,再由它把通信以某种方式**转发(transmit)**给各个 worker 进程。
每个进程独立占用内存
当程序把数据加载进内存时——例如把一个机器学习模型或一个大文件的内容放进变量——都会消耗服务器的 RAM。关键在于:多个进程之间通常不共享内存。每个运行中的进程都拥有自己独立的变量与内存;如果你的代码占用大量内存,那么每个进程都会等量占用。
一个直观的内存账本
假设你的代码要加载一个1 GB的机器学习模型:
- 运行 1 个进程 → 至少消耗1 GB RAM;
- 运行4 个进程(4 个 workers)→ 每个各占 1 GB,合计4 GB RAM。
如果你的服务器/虚拟机只有 3 GB RAM,却试图装载超过 4 GB 的数据,就会引发严重问题。🚨
在架构上,典型形态是:一个Manager Process负责启动和控制两个Worker Processes——前者通常监听 IP 上的端口并把通信转发下去,后者才是真正运行你的应用、接收请求并返回响应、把数据载入 RAM 的主体。当然同一台机器上除了你的应用还会有其它进程在运行。
一个值得注意的细节:每个进程的CPU 占用百分比随时间波动很大,而 **内存(RAM)**通常相对稳定。如果你的 API 每次计算量相近且客户端很多,那么 CPU 利用率一般也会趋于稳定,而不是剧烈震荡。
复制工具与策略示例
实现复制有多种途径,核心约束始终是:公共 IP 上的端口只能由一个组件处理,并且该组件必须能把通信转发给被复制的进程/worker。几种典型组合:
- Uvicorn +
--workers:一个 Uvicorn进程管理器监听 IP 和端口,并启动多个 Uvicorn worker 进程; - Kubernetes 等分布式容器系统:由 Kubernetes 层的某个组件监听 IP 和端口,通过运行多个容器实现复制,每个容器内跑一个 Uvicorn 进程;
- 云托管服务:云服务替你处理复制,通常允许你定义一个待运行进程或一个容器镜像,大概率仍是单个 Uvicorn 进程,再由云服务负责复制它。
关于容器镜像、Docker、Kubernetes 的深入细节,可参见 FastAPI in Containers - Docker 章节。
启动前的准备步骤(Previous Steps Before Starting)
很多情况下,你希望在应用启动之前先执行一些步骤——最典型的例子是数据库迁移(database migrations)。
为什么只能由单个进程执行
绝大多数情况下,这些步骤只应执行一次。因此你会希望用一个单独进程在应用启动前完成它们——即使应用本体之后会以多个进程(多 worker)方式运行,执行准备步骤的也必须恰好是一个进程。
原因在于:如果这些步骤被多个进程并行执行,就会重复劳动;而如果步骤是数据库迁移这类敏感操作,并行执行很可能彼此冲突。反之,如果某些准备步骤重复执行也无妨,那处理起来就简单得多。
另外要提醒的是:取决于你的部署形态,有些场景根本不需要任何启动前步骤——那自然不必操心这一切。
常见策略示例
准备步骤的落地方式高度依赖你的部署体系,并与进程启动、重启机制联动,常见思路包括:
- Kubernetes 中的 Init Container:在应用容器之前运行;
- bash 脚本:先执行准备步骤再启动应用——但该脚本本身仍需要一套启动/重启与错误检测机制。
用容器实现这一点的具体示例见 FastAPI in Containers - Docker。
资源利用率(Resource Utilization)
你的服务器本质上是一份资源:程序消费的是 CPU 上的计算时间与可用的 RAM 内存。那么,你究竟想消耗多少系统资源?
目标不是"越少越好"
直觉上容易认为"占用越少越好",但实际上你通常希望在不崩溃的前提下尽量多用:
- 如果你为 3 台服务器付费,却只用掉它们少量 RAM 与 CPU,那你多半在浪费钱,也在浪费电力;此时不如只保留 2 台服务器,把它们的 CPU、内存、磁盘、网络带宽等资源利用率提上去;
- 反过来,如果 2 台服务器的CPU 与 RAM 已被用到 100%,一旦某个进程再申请更多内存,服务器就不得不把磁盘当"内存"用(可能慢数千倍),甚至直接崩溃;或者某进程要做计算却要苦等 CPU 空闲。此时加购一台服务器、分流部分进程,让所有进程都有充足的 RAM 与 CPU 时间才是正解。
为流量尖峰留出余量
还存在一种可能:你的 API 因某种原因流量骤增——突然走红、被其它服务或爬虫盯上等。在这些情况下预留额外资源是明智的。官方给出的经验参考是给自己定一个目标区间,例如把资源利用率控制在50%~90%之间,并把 CPU 与 RAM 作为衡量与调优部署的核心指标。
观测手段可以从简单到复杂:用htop查看服务器整体或单进程的 CPU/RAM 用量,也可以引入跨服务器分布的更复杂的监控系统。
总结回顾
本文覆盖了决定 FastAPI 部署方式时需要时刻牢记的核心概念:
- 安全 —— HTTPS:由应用外部的 TLS Termination Proxy 提供,证书续期可由同一或另一组件负责;
- 开机自启:应用应由独立程序拉起,不依赖人工介入;
- 重启:失败后由外部组件自动拉起(与应用内错误被 FastAPI 隔离到单次请求不同,进程级崩溃必须靠进程外机制恢复);
- 复制(运行进程数):单端口监听 + 多 worker 分担请求,但每个进程的内存相互独立、线性叠加;
- 内存:按进程数成倍计算,必须纳入服务器选型;
- 启动前的准备步骤:如数据库迁移,只能由单个进程在启动前执行一次。
理解并运用这些概念,你就能在配置和调优部署时做出有依据的决策。更具体的可执行策略(HTTPS 配置、手动裸机部署、--workers参数、Docker/Kubernetes 容器化等)将在后续章节中逐一展开,可继续阅读 部署章节索引、Server Workers、手动部署 与 Docker 部署 获取完整的实战配方。🚀
【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考