Gunicorn 部署 #

为什么使用 Gunicorn? #

text
┌─────────────────────────────────────────────────────────────┐
│                    Gunicorn 优势                             │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   Uvicorn:                                                  │
│   - 单进程                                                  │
│   - 无法利用多核 CPU                                        │
│   - 进程崩溃需要手动重启                                     │
│                                                             │
│   Gunicorn + Uvicorn:                                       │
│   - 多进程管理                                              │
│   - 充分利用多核 CPU                                        │
│   - 自动重启崩溃进程                                        │
│   - 优雅重启                                                │
│   - 进程监控                                                │
│                                                             │
└─────────────────────────────────────────────────────────────┘

安装 #

bash
pip install gunicorn uvicorn[standard]

基本使用 #

命令行启动 #

bash
gunicorn main:app -w 4 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000

参数说明 #

参数 说明
-w 工作进程数
-k Worker 类
-b 绑定地址
--timeout 超时时间
--reload 自动重载(开发模式)

Gunicorn 配置 #

配置文件 #

python
import multiprocessing

bind = '0.0.0.0:8000'
workers = multiprocessing.cpu_count() * 2 + 1
worker_class = 'uvicorn.workers.UvicornWorker'
keepalive = 120
timeout = 120

启动 #

bash
gunicorn main:app -c gunicorn.conf.py

完整配置 #

python
import multiprocessing
import os

bind = '0.0.0.0:8000'

workers = int(os.getenv('WORKERS', multiprocessing.cpu_count() * 2 + 1))

worker_class = 'uvicorn.workers.UvicornWorker'

worker_connections = 1000

timeout = 120

keepalive = 5

threads = 1

max_requests = 1000
max_requests_jitter = 50

preload_app = True

accesslog = '-'
errorlog = '-'
loglevel = 'info'

def on_starting(server):
    print('Starting Gunicorn server')

def on_exit(server):
    print('Shutting down Gunicorn server')

def worker_exit(server, worker):
    print(f'Worker {worker.pid} exited')

def when_ready(server):
    print('Server is ready')

进程管理 #

工作进程数 #

python
import multiprocessing

workers = multiprocessing.cpu_count() * 2 + 1

预加载应用 #

python
preload_app = True

最大请求数 #

python
max_requests = 1000
max_requests_jitter = 50

日志配置 #

日志格式 #

python
accesslog = '-'
errorlog = '-'
loglevel = 'info'

access_log_format = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s" %(D)s'

日志文件 #

python
accesslog = '/var/log/gunicorn/access.log'
errorlog = '/var/log/gunicorn/error.log'

Systemd 服务 #

创建服务文件 #

ini
[Unit]
Description=FastAPI Application
After=network.target

[Service]
User=www-data
Group=www-data
WorkingDirectory=/var/www/my-api
Environment="PATH=/var/www/my-api/venv/bin"
ExecStart=/var/www/my-api/venv/bin/gunicorn main:app -c gunicorn.conf.py
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

服务管理 #

bash
sudo systemctl start my-api
sudo systemctl stop my-api
sudo systemctl restart my-api
sudo systemctl status my-api
sudo systemctl enable my-api

Nginx 配置 #

反向代理 #

nginx
upstream fastapi {
    server 127.0.0.1:8000;
    keepalive 32;
}

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://fastapi;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Connection "";
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }
}

负载均衡 #

nginx
upstream fastapi {
    least_conn;
    server 127.0.0.1:8000;
    server 127.0.0.1:8001;
    server 127.0.0.1:8002;
    keepalive 32;
}

性能优化 #

Worker 数量 #

python
workers = (2 * CPU_CORES) + 1

连接数 #

python
worker_connections = 1000

超时设置 #

python
timeout = 120
graceful_timeout = 30
keepalive = 5

线程 #

python
threads = 2
workers = multiprocessing.cpu_count()

完整示例 #

gunicorn.conf.py #

python
import multiprocessing
import os

bind = os.getenv('BIND', '0.0.0.0:8000')

workers = int(os.getenv('WORKERS', multiprocessing.cpu_count() * 2 + 1))

worker_class = 'uvicorn.workers.UvicornWorker'

worker_connections = 1000

timeout = int(os.getenv('TIMEOUT', 120))

graceful_timeout = 30

keepalive = 5

threads = int(os.getenv('THREADS', 1))

max_requests = 1000
max_requests_jitter = 50

preload_app = True

accesslog = os.getenv('ACCESS_LOG', '-')
errorlog = os.getenv('ERROR_LOG', '-')
loglevel = os.getenv('LOG_LEVEL', 'info')

access_log_format = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s" %(D)s'

def on_starting(server):
    server.log.info('Starting Gunicorn server')

def when_ready(server):
    server.log.info('Server is ready. Spawning workers')

def worker_int(worker):
    worker.log.info(f'Worker {worker.pid} received INT or QUIT signal')

def worker_abort(worker):
    worker.log.info(f'Worker {worker.pid} received SIGABRT signal')

启动脚本 #

bash
#!/bin/bash

export WORKERS=4
export TIMEOUT=120
export LOG_LEVEL=info

gunicorn app.main:app -c gunicorn.conf.py

下一步 #

现在你已经掌握了 Gunicorn 部署,可以开始实践 FastAPI 项目开发了!

最后更新:2026-03-29