← 返回题目列表

FastAPI 生产环境如何部署?需要注意哪些性能和稳定性问题?

高频 困难 第 15 / 27 题 更新于 2026/07/27
部署UvicornGunicorn性能优化稳定性

简化版

FastAPI 生产环境通常用 Uvicorn 作为 ASGI server,也可以用 Gunicorn 管理多个 Uvicorn worker,前面再接 Nginx 或网关。部署时要关注 worker 数量、超时、连接池、日志、健康检查、反向代理头、异步阻塞、优雅退出和安全配置。

详细版

常见部署结构:

Client -> Nginx / LB -> Gunicorn + UvicornWorker 或 Uvicorn workers -> FastAPI -> DB/Redis

关键注意点:

  • 不要在生产直接使用开发模式;
  • 根据 CPU、I/O、内存设置 worker 数量;
  • 异步接口内部不要调用阻塞代码;
  • 数据库连接池要结合 worker 数量配置;
  • 加健康检查接口;
  • 配置日志、指标、链路追踪;
  • 设置请求超时、上传大小限制、CORS、HTTPS;
  • behind proxy 时正确处理 forwarded headers;
  • 用 lifespan 做启动初始化和优雅关闭。

部署不是只把服务跑起来,而是让它能稳定、可观测、可恢复。

完整版教学

一、FastAPI 生产部署的基本结构

FastAPI 是 ASGI 应用,需要 ASGI 服务器运行。最常见的是 Uvicorn。简单启动命令类似:

uvicorn app.main:app --host 0.0.0.0 --port 8000

生产环境中,通常还会在前面放 Nginx、云负载均衡或 API 网关,负责 HTTPS、反向代理、限流、静态资源、请求大小限制等。

多进程部署可以用 Uvicorn 自带 workers:

uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 4

也可以用 Gunicorn 管理 Uvicorn worker:

gunicorn app.main:app -k uvicorn.workers.UvicornWorker -w 4

不同部署方式各有习惯和版本差异,核心是:FastAPI 需要 ASGI server,生产环境要考虑多进程、代理、日志、健康检查和优雅退出。

二、worker 数量怎么考虑

worker 数量不是越多越好。worker 多可以利用多核 CPU,也能提高隔离性:某个 worker 阻塞或崩溃,不一定影响全部请求。

但 worker 多也会增加内存占用。每个 worker 是独立进程,会加载一份应用、模型、连接池。如果应用加载了大模型,4 个 worker 可能就是 4 份模型内存。

数据库连接池也会被放大。假设每个 worker 连接池最大 20,4 个 worker 就可能产生 80 个数据库连接。很多生产事故不是 API 代码错,而是 worker 和连接池乘起来超过数据库上限。

因此设置 worker 要综合 CPU 核数、请求类型、内存、数据库连接数和模型大小。

三、异步阻塞是 FastAPI 生产性能大坑

FastAPI 支持异步,但生产中常见问题是 async def 里调用同步阻塞库:

@app.get("/bad")
async def bad():
    resp = requests.get("https://example.com")
    return resp.json()

这个接口看起来是异步,实际上 requests.get() 会阻塞事件循环。正确做法是使用异步客户端:

async with httpx.AsyncClient() as client:
    resp = await client.get("https://example.com")

数据库也是一样。同步 ORM 可以放在普通 def 路由或线程池里,全链路异步则要使用异步驱动和 AsyncSession

四、反向代理和 forwarded headers

生产环境常见链路是客户端先到 Nginx 或负载均衡,再转发给 FastAPI。此时 FastAPI 看到的客户端 IP、协议可能是代理的地址和 HTTP,而不是用户真实来源和 HTTPS。

如果应用需要生成绝对 URL、记录真实 IP、判断是否 HTTPS,就要正确配置代理头,例如 X-Forwarded-ForX-Forwarded-Proto。同时必须只信任可信代理,不能盲目信任外部用户伪造的 forwarded headers。

Nginx 还要处理 WebSocket upgrade、流式响应缓冲、上传大小、超时等配置。特别是 WebSocket 和 SSE,如果代理缓冲或超时设置不当,会出现本地正常、线上断流的问题。

五、健康检查和优雅退出

生产服务需要健康检查接口,例如:

@app.get("/health")
def health():
    return {"status": "ok"}

更完善的健康检查可以区分 liveness 和 readiness。liveness 表示进程还活着,readiness 表示应用已经准备好接流量,比如数据库连接可用、模型加载完成。

优雅退出也很重要。服务发布或容器停止时,应停止接新请求,等待已有请求处理完成,再关闭连接池和后台任务。FastAPI 的 lifespan 可以用于关闭阶段释放资源。

六、日志、指标和追踪

生产环境必须可观测。至少要有结构化日志、错误日志、访问日志。更进一步可以接入 Prometheus 指标、OpenTelemetry 链路追踪、APM 平台。

常见指标包括请求量、响应时间、错误率、数据库连接池使用情况、外部依赖耗时、worker 重启次数。没有这些信息,线上慢请求和偶发错误很难定位。

Trace ID 很实用。可以在中间件里为每个请求生成 trace id,写入日志并返回响应头。用户反馈问题时,拿 trace id 可以串起整条链路。

七、安全和稳定性配置

生产环境不要开启调试模式。CORS 要按实际前端域名配置,不要为了省事长期允许所有来源和所有凭证。

请求体大小、上传文件大小、接口超时、慢请求保护都要配置。否则一个大文件或慢连接就可能占用大量资源。

敏感配置通过环境变量或密钥管理系统注入,不要提交到代码仓库。数据库密码、JWT 密钥、第三方 API Key 都属于敏感信息。

八、常见误区与追问

部署项面试要点常见风险
Worker结合 CPU、内存、I/O、连接池配置worker 过多导致内存和 DB 连接爆掉
反向代理HTTPS、超时、上传大小、WebSocket、forwarded headers真实 IP 和协议识别错误
可观测性日志、指标、Trace ID、健康检查出问题只能靠猜
2 台机器 * 每台 4 worker * 每 worker pool_size=10
仅 API 服务就可能占用 80 个数据库连接。
再加 max_overflow=10 时,峰值可能到 160 个连接。

易错点:生产部署不是把 Uvicorn 跑起来,而是让服务在流量、故障、发布和排查时都可控。

  • 误区:生产环境直接用开发启动方式就够了。 生产需要多 worker、反向代理、日志、健康检查、超时、优雅退出和安全配置。
  • 误区:worker 越多吞吐越高。 worker 会复制应用内存、模型和连接池,过多可能先压垮内存或数据库连接数。
  • 误区:异步框架可以忽略阻塞调用。 requests、同步 ORM、CPU 大循环仍会拖慢事件循环或耗尽线程池。
  • 追问:为什么要区分 liveness 和 readiness? liveness 用于判断进程是否需要重启,readiness 用于判断是否已经完成初始化、可以接收流量。
  • 追问:反向代理头为什么不能盲目信任? 外部用户可以伪造 X-Forwarded-For,只有来自可信代理的转发头才应该被应用采信。
  • 追问:线上慢请求怎么定位? 需要访问日志、业务日志、Trace ID、外部依赖耗时、数据库慢查询和指标监控共同定位,而不是只看接口代码。

九、加强记忆

记 FastAPI 生产部署,不是只会写 uvicorn main:app。完整答案要覆盖 ASGI server、worker、反向代理、连接池、异步阻塞、健康检查、优雅退出、日志指标和安全配置。真正的生产稳定性来自这些工程细节。