ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

FastAPI 部署实践:用 Uvicorn 多 Worker 进程(`--workers`)榨干多核 CPU

FastAPI 部署实践:用 Uvicorn 多 Worker 进程(`--workers`)榨干多核 CPU FastAPI 部署实践用 Uvicorn 多 Worker 进程--workers榨干多核 CPU【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi多进程复制Replication是 FastAPI 生产部署六大核心概念之一单个 Uvicorn 进程只能使用单个 CPU 核心而通过--workers启动多个 Worker 进程可以让同一份应用并行处理更多请求。本篇以 FastAPI 官方文档《Trabalhadores do Servidor - Uvicorn com Trabalhadores》Server Workers为骨架结合当前仓库的 CLI 源码与测试系统讲解fastapi与uvicorn两条启动路径下 Worker 进程的完整用法、底层进程模型、内存约束以及与 Docker/Kubernetes 方案的取舍。回顾部署六大概念与单进程现状在深入 Worker 之前先回顾部署必须考虑的六类概念详见 部署概念 与 英文版安全Security——HTTPS开机启动Running on startup自动重启Restarts复制Replication即运行进程的数量内存Memory启动前的前置步骤Previous steps before starting在整个 FastAPI 教程的前半段无论是fastapi run还是直接运行 Uvicorn你运行的其实都是单进程的服务程序。所谓单进程能同时服务多个客户端是因为单个事件循环内部可以并发处理 I/O但在多核 CPU上一个进程同一时刻只能占用一个核心。当请求量上来、单进程成为瓶颈时就需要进程级复制让同一份应用跑出多个进程共同分摊请求。多 Worker 启动两种等价方式官方给出的核心选项只有一个--workers。通过它告诉 Uvicorn 启动指定数量的 Worker 进程。方式一使用fastapi命令使用仓库自带 CLI 入口由 fastapi/cli.py 分发到fastapi-cli包实现启动命令如下$ fastapi run --workers 4 main.py FastAPI Starting production server Searching for package file structure from directories with __init__.py files Importing from /home/user/code/awesomeapp module main.py code Importing the FastAPI app object from the module with the following code: from main import app app Using import string: main:app server Server started at http://0.0.0.0:8000 server Documentation at http://0.0.0.0:8000/docs Logs: INFO Uvicorn running on http://0.0.0.0:8000 (Press CTRLC to quit) INFO Started parent process [27365] INFO Started server process [27368] INFO Started server process [27369] INFO Started server process [27370] INFO Started server process [27367] INFO Waiting for application startup. INFO Waiting for application startup. INFO Waiting for application startup. INFO Waiting for application startup. INFO Application startup complete. INFO Application startup complete. INFO Application startup complete. INFO Application startup complete.fastapi命令会自动探测模块结构寻找含__init__.py的包目录、解析出main:app这个导入字符串默认监听0.0.0.0:8000并同时提供/docs交互式文档。CLI 入口与可选依赖的定义可以在 pyproject.toml 的[project.scripts]中看到fastapi fastapi.cli:main若未安装提供 CLI 的fastapi-clifastapi/cli.py 会明确提示安装fastapi[standard]。该行为被 tests/test_fastapi_cli.py 覆盖验证。方式二直接使用uvicorn命令如果你更习惯直接控制 Uvicorn也可以绕过fastapi命令$ uv run uvicorn main:app --host 0.0.0.0 --port 8080 --workers 4 INFO: Uvicorn running on http://0.0.0.0:8080 (Press CTRLC to quit) INFO: Started parent process [27365] INFO: Started server process [27368] INFO: Waiting for application startup. INFO: Application startup complete. INFO: Started server process [27369] INFO: Waiting for application startup. INFO: Application startup complete. INFO: Started server process [27370] INFO: Waiting for application startup. INFO: Application startup complete. INFO: Started server process [27367] INFO: Waiting for application startup. INFO: Application startup complete.这里除了--workers之外没有任何新概念——--host、--port、main:app的写法都与此前单进程方式一致唯一的增量就是--workers 4。关键日志解读父进程与 Worker 进程的 PID对比上面两份日志能看到完全相同的信息结构Started parent process [27365]——这是父进程Parent Process也就是**进程管理器Process Manager**的 PID随后依次出现Started server process [27368]、[27369]、[27370]、[27367]——这是四个Worker 进程的 PID日志中出现四次Waiting for application startup.和四次Application startup complete.说明每个 Worker 进程都会各自完整地执行一次应用启动流程包括 FastAPI 的 lifespan 启动事件。底层进程模型为什么需要一个父进程 N 个 WorkerWorker 的架构并非多个进程各自抢同一个端口。回忆部署概念文档docs/pt/docs/deployment/concepts.md强调的事实一台服务器上同一个 IP 与端口的组合只能被一个进程监听。因此多进程方案必须遵循如下结构**唯一的进程管理器父进程**负责监听 IP 与端口把进来的通信分发给各个 Worker多个 Worker 进程各自独立运行你的应用代码真正执行接收请求 → 计算 → 返回响应的主逻辑每个进程内部加载进 RAM 的一切模型权重、缓存、大文件内容都是各自独立的一份——多进程通常不共享内存。在 Uvicorn 的多 Worker 模式下父进程就是那个唯一监听者--workers的数量决定它孵化出的子进程数。这套Manager Workers的复制策略在部署概念文档的复制工具与策略示例中被明确列为第一种方案docs/pt/docs/deployment/concepts.mdUvicorn 的进程管理器监听 IP 与端口并启动多个 Uvicorn Worker 进程。启动事件会执行 N 次日志中四次Application startup complete.是最容易被忽视的副作用应用启动lifespan/startup会在每个 Worker 中分别执行一次。这意味着若你在启动事件里加载了大型 ML 模型那么--workers 4就会加载 4 份若你在启动事件里调度了定时任务它会以 4 份的形式分别在 4 个进程中运行任何每进程一份的内存开销都会按 Worker 数量成倍放大。内存约束Worker 数量 × 单进程内存占用这是使用 Worker 前必须做好的算术题。部署概念文档给出了非常直观的例子docs/pt/docs/deployment/concepts.md若你的代码在变量中加载了1 GB的机器学习模型跑 1 个进程至少消耗 1 GB RAM若启动4 个进程4 个 Worker每个各占 1 GB总共消耗4 GB RAM。而如果服务器/虚拟机只有 3 GB 内存强行加载超过 4 GB 就会出问题。因此--workers并非越大越好。选择 Worker 数量时应同时权衡服务器 CPU 核心数复制是为了利用多核并行、总可用内存与单进程内存占用、以及这台机器上是否还跑着数据库等其他进程。一般做法是先实测单进程的内存基线再反推安全的 Worker 上限。部署概念清单Worker 解决了什么还有什么没解决回到开头的六大概念对照勾选结果如下官方原文结论复制Replication——✅ Worker 的主要作用直接解决重启Restarts——⚠️ 部分帮助进程管理器可以在一定程度上管理 Worker 生命周期但文档明确说明对重启只是一点点帮助安全 HTTPS——❌ 仍需独立处理通常由 TLS 终止代理完成开机启动Running on startup——❌ 仍需外部机制systemd、supervisor 等保证服务随系统启动内存Memory——❌ 仍需你按每进程一份来规划容量启动前前置步骤Previous steps——❌ 如数据库迁移这类只能执行一次的操作仍需一个独立单进程在应用启动前完成绝不能交给 N 个 Worker 并行执行否则会互相冲突、重复执行docs/pt/docs/deployment/concepts.md。一句话总结--workers只是复制这一个环节的答案而不是完整的生产部署方案。容器与 Docker 场景Kubernetes 里通常反而不需要 Worker文档特别提示了一个常见误区如果你在使用 Docker、Kubernetes 等容器方案请阅读下一章 FastAPI 容器化 - Docker英文原版见 docker.md。其中最关键的一条建议是在 Kubernetes 上运行时通常不应当使用 Worker而是每个容器只跑一个 Uvicorn 进程。原因在于Kubernetes 这类分布式容器管理系统本身就负责复制你只需把**副本数replica**扩大让平台调度出多个容器即可每个容器内一个 Uvicorn 进程配合 Kubernetes 的存活/就绪探针与自动重启策略恰好能覆盖重启开机启动内存隔离等多个概念若在容器内再叠加--workers与平台的副本调度机制会相互叠加、难以精细控制也违背了一个容器一个进程的常见最佳实践。Docker 章节会演示如何从零构建只运行单个 Uvicorn 进程的镜像——这是配合分布式容器系统时推荐采用的形态。适用场景小结--workers这条路径最适合的场景是你自己搭建部署系统不使用托管容器平台例如直接在裸机/虚拟机上配合 systemd、Supervisor 等进程管理器自己承担 HTTPS 终止代理、开机启动、自动重启与内存规划。此时通过一行命令即可获得进程级并行能力fastapi run --workers 4 main.py # 或 uvicorn main:app --host 0.0.0.0 --port 8080 --workers 4总结回顾使用--workers N配合fastapi run或uvicorn命令可以启动N 个并行 Worker 进程充分利用多核 CPU显著提升请求处理吞吐日志中的parent process是进程管理器多个server process是真正的 Worker每个 Worker 独占一份内存Worker 数量必须与 CPU 核心数、总内存预算一起规划Worker 只解决复制HTTPS、开机启动、重启、内存、前置步骤仍需自行处理或交给容器平台若已使用 Kubernetes 等分布式容器系统优先选择每容器单 Uvicorn 进程 平台副本调度而不是容器内多 Worker。下一步请阅读 FastAPI 容器化 - Docker了解容器与 Kubernetes 如何用更简单的方式补齐其余部署概念。【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表