FastAPI 生产部署核心概念:HTTPS、进程与 Worker、自动重启与资源利用率
2026/9/7 18:02:29 网站建设 项目流程

FastAPI 生产部署核心概念:HTTPS、进程与 Worker、自动重启与资源利用率

【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi

部署一个 FastAPI 应用(事实上,任何 Web API 都是如此)时,真正决定架构成败的往往不是框架本身,而是围绕它的六个核心概念:安全(HTTPS)、开机自启、故障重启、进程复制(Worker 数量)、内存、以及启动前的准备步骤。理解这些概念后,你就能针对任意环境——包括尚不存在的未来环境——评估并设计出最适合自己的部署方案。本文基于 FastAPI 官方文档中的部署概念章节(docs/en/docs/deployment/concepts.md),结合仓库源码与配套文档,系统梳理这些概念的含义、约束条件与落地工具选型。

六大部署概念总览

官方文档把部署决策归纳为以下六个必须考量的维度:

  1. 安全 - HTTPS:如何为 API 提供加密传输;
  2. Running on startup(开机自启):如何保证应用进程在服务器启动后自动运行;
  3. Restarts(重启):进程崩溃后如何自动拉起;
  4. Replication(复制/进程数):同时运行多少个进程来处理请求;
  5. Memory(内存):每个进程的内存占用如何叠加到整机上;
  6. Previous steps before starting(启动前步骤):如何以单进程方式先执行数据库迁移等一次性任务。

最终目标是:以安全的方式服务 API 客户端,避免服务中断,并尽可能高效地利用计算资源(例如远程服务器/虚拟机)。官方文档强调,这些概念适用于任何类型的 Web API,掌握它们是为了获得“直觉”——即在不同环境中做出正确部署决策的判断力。

安全:HTTPS 与 TLS 终结代理

TLS 终结:加密由谁负责

如官方 HTTPS 指南 所述,HTTPS 为 API 提供传输加密,而通常情况下,HTTPS 是由一个位于应用服务器外部的组件提供的,即TLS 终结代理(TLS Termination Proxy)。此外,还必须有一个组件负责HTTPS 证书的续期——它可以是同一个组件,也可以是另外的组件。

常见的 TLS 终结工具组合

文档给出的可选工具清单如下(证书续期方式各异,选型时重点关注):

工具证书续期方式
Traefik自动处理证书续期
Caddy自动处理证书续期
Nginx需要外部组件,如 Certbot
HAProxy需要外部组件,如 Certbot
Kubernetes + Ingress Controller(如 Nginx)需要外部组件,如 cert-manager
云服务商内部托管云服务作为其服务的一部分内部处理(可能有限制或额外费用,但无需自己搭建 TLS 终结代理)

选择云服务方案时,它可能有一些限制或更高的费用,但省去了自行配置 TLS 终结代理的工作。具体的部署示例在后续章节(如 手动部署、Docker 部署)中给出。

程序(Program)与进程(Process)的区别

部署语境下会频繁提到“运行中的进程(process)”,因此必须先厘清它与“程序(program)”的区别。

“程序”一词的多重含义

Program一词常被用来指代很多不同的东西:

  • 你编写的代码,即那些Python 文件
  • 操作系统可以执行文件,例如pythonpython.exeuvicorn
  • 某个正在操作系统上运行的特定程序实例,它占用 CPU、在内存中存储数据——这个东西也被称为进程(process)

“进程”的确切定义

Process的用法更具体,只指操作系统中正在运行的那个东西:

  • 指文件,指代码,而是特指正在被执行、由操作系统管理的那个实体;
  • 任何程序、任何代码,只有正在被执行(即有进程在运行)时才能“做事”;
  • 进程可以被你或操作系统终止(kill),终止后它停止运行,也就不再能做任何事;
  • 你电脑上运行的每个应用背后都有若干进程,每个窗口、每个运行中的程序都对应进程,一台开机运行的电脑通常同时有大量进程
  • 同一程序的多个进程可以同时运行

打开操作系统的“任务管理器”或“系统监视器”类工具就能看到这一点。例如,通常能观察到多个进程正在运行同一个浏览器程序(Firefox、Chrome、Edge 等)——浏览器通常为每个标签页启动一个进程,外加若干辅助进程:

理解了程序与进程的区别,下面讨论的所有部署策略才有了共同的语义基础。

开机自启:让应用常驻

大多数情况下,Web API 需要持续运行、不中断,让客户端随时可访问(除非你有特定理由只想让它在某些情况下运行)。

在远程服务器上手动启动的问题

在远程服务器(云服务器、虚拟机等)上最简单的方式是手动运行fastapi run(它使用 Uvicorn)或类似命令,就像本地开发时那样。这在开发阶段没问题,但有两个致命风险:

  • 如果到服务器的连接中断,运行中的进程很可能随之死亡
  • 如果服务器被重启(例如系统更新、云厂商迁移后),你很可能根本察觉不到,也就不会去手动重启进程,API 会一直死着。

自动启动与“独立程序”

因此通常需要让服务器程序(如 Uvicorn)在服务器启动时自动启动,无需任何人工干预,保证始终有一个进程在运行你的 API。

实现方式是引入一个独立的程序(separate program),它负责保证你的应用开机即运行;在很多场景下,它还负责启动其他组件(例如数据库)。文档列出的候选工具:

  • Docker
  • Kubernetes
  • Docker Compose
  • Docker in Swarm Mode
  • Systemd
  • Supervisor
  • 云服务商作为其服务的一部分内部托管
  • 其他方案

仓库视角:fastapi run从哪里来

从源码结构看,fastapi命令行入口本身只是一个薄封装:fastapi/cli.py 尝试从fastapi_cli包导入真正的 CLI 实现,若未安装则抛出提示To use the fastapi command, please install "fastapi[standard]"RuntimeError。对应的入口注册与依赖声明见 pyproject.toml 中的[project.scripts]fastapi = "fastapi.cli:main")以及standard可选依赖(包含uvicorn[standard])。这一行为由测试 tests/test_fastapi_cli.py 验证:未安装fastapi_cli时调用fastapi.cli.main()会抛出带安装提示的异常。换言之,部署文档中说的“fastapi run(使用 Uvicorn)”在实现上依赖于fastapi[standard]提供的uvicorn[standard],这是生产部署前应确认的前置条件。

故障重启:从局部 500 到进程级崩溃

与开机自启类似,你还需要确保应用在故障后被重启

人的错误与小错误的自动兜底

人类会不断犯错,软件几乎总有一些隐藏的 bug,开发者在修复旧 bug、开发新功能的过程中也在持续引入新变化。值得庆幸的是,用 FastAPI 构建 Web API 时,如果代码中出现错误,FastAPI 通常会把错误限制在触发它的那单个请求内:客户端收到该请求的500 Internal Server Error,而应用继续为后续请求正常工作,不会整体崩溃。

进程级崩溃与自动重启

但确实存在会让整个应用崩溃的代码,使 Uvicorn 和 Python 进程直接挂掉。即便如此,你通常也不希望应用因为一处的错误就“死掉”,而是希望它至少为那些没坏的 path operation继续服务。

对于这类导致运行中进程崩溃的严重错误,你需要一个外部组件负责重启该进程——因为进程已经死了,应用自身的代码此时已无能为力。文档特别提醒:如果应用是一启动就立刻崩溃,那无限重启就没有意义了——这种情况你通常会在开发期或刚部署后就发现。我们应聚焦的主体场景是:应用未来在某些特定情况下可能完全崩溃,此时重启是有价值的。

在大多数情况下,负责开机自启的同一个工具也负责自动重启,例如:Docker、Kubernetes、Docker Compose、Docker in Swarm Mode、Systemd、Supervisor、云服务商内部托管等。

复制:Worker 进程、端口约束与内存

使用fastapi命令(运行 Uvicorn)时,一个进程就能并发服务多个客户端。但很多场景下你需要同时运行多个worker 进程

多进程与单端口约束

如果客户端数量超过单进程的处理能力(比如虚拟机不大),而服务器 CPU 有多个核心,就可以让多个进程运行同一应用,把请求分发到它们之间。运行同一 API 程序的多个进程通常被称为workers

这里有一个硬约束:同一 IP 与端口的组合只能有一个进程监听(这一点在 HTTPS 指南 中也有说明)。因此要同时存在多个进程,就必须有一个进程监听端口,再以某种方式把通信转发给各个 worker 进程。

每个进程独立的内存占用

程序在内存中加载的东西——例如把一个机器学习模型赋给变量、把大文件内容读进变量——都会消耗服务器的 RAM。而多个进程之间通常不共享任何内存:每个运行中的进程拥有自己的变量与内存。如果你的代码占用大量内存,每个进程都会占用一份等量的内存。

具体算一笔账:假设你的代码加载了一个1 GB 的机器学习模型,运行 1 个进程时至少消耗 1 GB RAM;启动4 个 worker时,每个消耗 1 GB,API 总共消耗4 GB RAM。如果服务器只有 3 GB RAM,加载超过 4 GB 就会出问题。

Manager 进程与 Worker 进程的结构

官方文档用一张图说明典型结构:一个Manager Process(管理器进程)启动并控制多个Worker Process。管理器进程负责在 IP 的某个端口上监听,并把所有通信转发给 worker 进程;worker 进程则真正运行你的应用——接收请求、返回响应、执行主要计算,并把代码中赋给变量的任何东西加载进 RAM。同一台机器上通常还运行着其他进程。该图见 process-ram.drawio.svg。

一个值得注意的观察:各进程占用的CPU 百分比可能随时间大幅波动,而**内存(RAM)**通常相对稳定。如果你的 API 每次请求的计算量相近且客户端很多,CPU 利用率大概率也会趋于稳定(而不是快速上下抖动)。

常见复制策略与工具

主要约束始终不变:必须有单一组件处理公网 IP 上的端口,然后它需要有某种方式把通信转发给被复制的进程/worker。文档给出的策略组合:

  • Uvicorn +--workers:一个 Uvicorn管理器进程监听 IP 和端口,并启动多个 Uvicorn worker 进程
  • Kubernetes 等其他分布式容器系统:Kubernetes 层的某个组件监听 IP 和端口,复制方式是多个容器,每个容器内运行一个 Uvicorn 进程
  • 代劳的云服务:云服务通常替你处理复制——你可能只需定义要运行的进程或容器镜像,而大概率是单个 Uvicorn 进程,由云服务负责复制。

关于第一条策略,仓库中配套的 Uvicorn Workers 文档 给出了可复制的实证:执行fastapi run --workers 4 main.py后,日志会依次输出Started parent process [27365]与 4 条Started server process [...],直观印证了上文“一个管理器进程 + N 个 worker 进程”的结构。文档同时提示:若使用 Docker/Kubernetes,在 Kubernetes 上通常不希望在单个容器里用 workers,而是每个容器跑单个 Uvicorn 进程,交由容器层做复制(详见 Docker 部署指南)。

启动前的准备步骤(Previous Steps)

很多场景下,你需要在启动应用之前执行某些步骤,最典型的例子是运行数据库迁移。但多数情况下这些步骤只需要执行一次,因此:

  • 需要一个单一进程来执行这些前置步骤,然后再启动应用;
  • 必须确保即使之后应用本身以多进程(多 worker)方式运行,前置步骤也只由单进程执行。如果这些步骤被多个进程并行执行,就会重复劳动;如果步骤是数据库迁移这类敏感操作,并行执行还可能互相冲突
  • 当然,也存在某些前置步骤可以安全地重复执行的情况,那样处理就简单得多。另外取决于你的架构,有些情况下根本不需要任何前置步骤,那就完全不用考虑这一节。

文档给出的可选策略:

  • Kubernetes 中的 "Init Container":在你的应用容器之前运行;
  • bash 脚本:先执行前置步骤,再启动应用——注意你仍然需要一种方式来启动/重启这个 bash 脚本本身、检测错误等。

更具体的容器化示例官方文档指向了 Docker 部署章节。

资源利用率:把付费资源用满,但别撑爆

你的服务器是资源,你的程序消耗其中的 CPU 计算时间和 RAM。你希望占用多少资源?直觉上可能觉得“别太多”,但现实中你大概率希望在不崩溃的前提下占用尽可能多

  • 如果你付了 3 台服务器的钱却只用了很少的 RAM 和 CPU,那基本是浪费钱、也浪费电力。这时可能用 2 台服务器并把资源利用率(CPU、内存、磁盘、网络带宽等)提得更高更划算;
  • 反过来,如果 2 台服务器的CPU 和 RAM 都用到 100%,某个进程迟早会请求更多内存,服务器将被迫把磁盘当作内存使用(可能慢数千倍)甚至崩溃;或者某个进程需要计算却只能等 CPU 空闲。此时应该多加一台服务器,把部分进程放上去,让所有进程都有足够的 RAM 和 CPU 时间
  • 还要考虑流量尖峰:应用可能突然走红,或有其他服务、机器人开始使用它,你需要冗余资源来应对这种情况。

实践建议:可以设定一个目标利用率区间,例如 50%~90%。关键是这些指标(CPU 与内存利用率)就是你调优部署时最主要需要度量的对象。度量工具可以从简单的htop(查看整机或单进程的 CPU/RAM 占用)开始,也可以升级到更复杂的、跨服务器分布的监控工具。

小结:六个概念的清单

回顾本章建立的核心概念清单,它们是你决定如何部署应用时应该持续放在心上的:

概念关键问题典型工具/手段
安全 - HTTPS谁终结 TLS?谁续期证书?Traefik / Caddy(自动续期);Nginx / HAProxy + Certbot;K8s Ingress + cert-manager;云服务托管
开机自启服务器重启后进程如何自动回来?Docker、Kubernetes、Docker Compose、Swarm、Systemd、Supervisor、云托管
自动重启进程崩溃后谁来拉起?通常与自启为同一外部组件
复制(进程数)单端口只能一个进程,如何多进程?Uvicorn--workers(管理器进程)、K8s 多容器、云服务复制
内存每个 worker 各占一份内存,总量如何规划?以模型/大对象大小 × worker 数估算
启动前步骤数据库迁移等一次性任务如何只跑一次?K8s Init Container、bash 脚本
资源利用率用多少资源合适?htop或分布式监控,目标区间 50%~90%

掌握这些概念并知道如何应用,是你在配置和调优部署时做出任何决策所需的直觉基础。在这份概念清单之上,官方文档的后续章节(HTTPS、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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询