🦄 Gunicorn 部署指南

从配置方式到 Worker 选型,一文讲清楚 Gunicorn 如何搭配 uvicorn 部署 Python Web 应用

Gunicorn Uvicorn ASGI / WSGI FastAPI · Flask Worker 选型
1
前置知识:为什么需要 Gunicorn?

在开发阶段,你直接用 uvicorn main:app 就能跑起来。
但在生产环境中,你需要一个进程管理器来:

  • 管理多个 Worker 进程(利用多核 CPU,提高并发能力)
  • 自动重启崩溃的 Worker(保证服务高可用)
  • 优雅的启动与停止(graceful shutdown,不丢失请求)
  • 负载均衡(master 进程将请求分发给各个 worker)
💡 核心关系一句话 Gunicorn 是「老板」(进程管理器),uvicorn 是「干活的员工」(ASGI 服务器)。
你用 Gunicorn 来管 uvicorn 的多个实例,而不是直接裸跑 uvicorn。
2
两种配置方式:配置文件 vs 命令行参数
📄 方式一:配置文件(推荐)

创建 gunicorn_config.py

# gunicorn_config.py
import multiprocessing

# 绑定地址和端口
bind = "0.0.0.0:8000"

# Worker 进程数(建议 CPU 核数 × 2 + 1)
workers = multiprocessing.cpu_count() * 2 + 1

# Worker 类(关键!)
worker_class = "uvicorn.workers.UvicornWorker"

# 超时设置
timeout = 120

# 日志配置
accesslog = "-"
errorlog = "-"

# 日志级别
log_level = "info"

启动命令:
gunicorn -c gunicorn_config.py main:app

⌨️ 方式二:命令行参数

所有参数写在命令里:

gunicorn \
  main:app \
  -w 4 \
  -k "uvicorn.workers.UvicornWorker" \
  -b "0.0.0.0:8000" \
  --timeout 120
⚠️ 注意 参数多的时候命令会很长,容易写错。生产环境推荐使用配置文件方式。

📋 关键参数速查表

参数 含义 推荐值
-w / workers Worker 进程数量 CPU 核数 × 2 + 1
-k / worker_class Worker 工作模式(核心!) 见下方详细表格
-b / bind 绑定地址:端口 0.0.0.0:8000
--timeout Worker 超时时间(秒) 120 或 300
-c 指定配置文件路径 gunicorn_config.py
3
Worker Class 完全解析(重点!)

worker_class 决定了 Gunicorn 的 Worker 用什么模式处理请求, 这是整个配置中最关键的一个参数。

🔄 同步 vs 异步 — 先搞清概念

🔵 同步 Worker (Sync)

一个 Worker 同时只能处理一个请求。
如果请求 A 在等数据库响应,这个 Worker 就被阻塞了,
请求 B 必须排队等待。

🟣 异步 Worker (Async)

一个 Worker 可以同时处理多个请求。
当请求 A 在等 IO 时,Worker 切去处理请求 B。
高并发场景下效率远高于同步。

📊 全部 Worker 类型一览

worker_class 说明 适用场景
sync
(默认)
同步 Worker,每个请求独占一个进程/线程 Flask/Django 等 WSGI 应用;低并发、CPU 密集型任务
gevent 异步 Worker,基于 gevent 协程库 高并发 I/O 密集型;长连接(WebSocket、聊天室)
eventlet 异步 Worker,基于 eventlet 协程库 同 gevent,I/O 密集型高并发
tornado Tornado 框架的 Worker 已有 Tornado 应用的迁移场景
gthread 线程 Worker 需要线程并发的混合场景
uvicorn.workers.UvicornWorker Uvicorn ASGI Worker(最常用!) FastAPI / Starlette(我们用的就是这个)
uvicorn.workers.UvicornH11Worker Uvicorn + H11 纯 Python 实现 不需要 uvloop 时使用(兼容性更好)
✅ FastAPI / StarAPI 项目直接选这个
如果你用的是 FastAPI 或 Starlette(ASGI 框架),worker_class 必须设置为
"uvicorn.workers.UvicornWorker",否则无法正确处理异步请求。
⚠️ requirements.txt 已经装了 uvicorn[standard]
使用 UvicornWorker 前,确保安装了完整版 uvicorn:
pip install "uvicorn[standard]" (包含 uvloop、httptools 等加速组件)
4
项目升级:如何选择 Worker?

不同类型的项目升级,应该怎么选?

🚀

Flask / Django 传统 WSGI 项目 → 不变或加 gevent

WSGI 项目继续用默认的 sync worker 即可。如果有大量长连接需求,可换为 gevent

# Flask 默认即可
gunicorn app:app -w 4

# 或用 gevent 处理长连接
gunicorn app:app -w 4 -k gevent

FastAPI / Starlette 项目 → 必须 UvicornWorker

ASGI 框架必须配合 UvicornWorker 才能发挥异步优势。

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

UvicornWorker + 多个 worker 并发

每个 worker 都是一个独立的 uvicorn 进程,Gunicorn master 负责在它们之间分发请求。

# 4 个 UvicornWorker 并发运行
gunicorn main:app -w 4 \
  -k "uvicorn.workers.UvicornWorker"
  # ↓ 等价于同时跑 4 个 uvicorn 进程
🐍

纯 Python 环境(无 uvloop)→ 用 UvicornH11Worker

如果服务器环境不支持 uvloop(如某些 ARM 平台、Windows),用纯 Python 实现的 H11Worker 作为替代。

gunicorn main:app \
  -w 4 \
  -k "uvicorn.workers.UvicornH11Worker"
5
选型决策流程
你的框架是?
FastAPI / Starlette
UvicornWorker ✅
-k uvicorn.workers.UvicornWorker
Flask / Django (WSGI)
sync (默认)
-k sync
↓ 特殊情况
高并发长连接?→ gevent / eventlet
无 uvloop 支持?→ UvicornH11Worker
6
常见踩坑 & FAQ
❌ 最常见的错误 直接用 gunicorn main:app -w 4 跑 FastAPI,
没有指定 -k uvicorn.workers.UvicornWorker

结果:Gunicorn 用默认的 sync worker 来跑,所有异步功能失效,性能暴跌!

Q & A

Q: 为什么不用 uvicorn 自带的多 worker 模式?
uvicorn 本身支持 --workers 参数,但它只是简单 fork 进程,没有 Gunicorn 的优雅重启、进程监控、自动恢复等能力。生产环境推荐 Gunicorn + UvicornWorker 的组合。
Q: worker 数量设多少合适?
经验公式:(CPU 核心数 × 2) + 1
4 核机器 → 9 workers;8 核机器 → 17 workers。
I/O 密集型可以适当增加,CPU 密集型则适当减少。
Q: gevent 和 UvicornWorker 怎么选?
如果你的框架本身就是异步的(FastAPI/Starlette),优先用 UvicornWorker——它原生支持 ASGI 异步协议。
gevent 更适合把传统同步应用「魔改」成伪异步的场景。
Q: 配置文件和命令行参数冲突了怎么办?
命令行参数优先级更高,会覆盖配置文件中的同名参数。所以最佳实践是:通用配置放文件,临时调试覆盖用命令行。