#Nginx + Gunicorn/Uvicorn:生产环境下的高性能反向代理配置
📂 所属阶段:第五阶段 — 工程化与部署(实战篇)
🔗 相关章节:Docker 容器化部署 · Pydantic Settings 多环境配置
#1. 为什么需要 Nginx?
#1.1 直接暴露 Uvicorn 的问题
直接: 客户端 → Uvicorn(单进程,单 worker,无限速)
问题:并发受限,无 SSL,无静态文件优化
Nginx: 客户端 → Nginx → Uvicorn(多 worker,SSL 终结,限速,静态文件)
优势:高性能反向代理 + 负载均衡 + 安全保护#1.2 Nginx 的核心作用
| 功能 | 说明 |
|---|---|
| SSL/TLS 终结 | 处理 HTTPS,Uvicorn 只需跑 HTTP |
| 静态文件 | 高效处理 CSS/JS/图片,释放 Python |
| 负载均衡 | 多 worker 分配请求 |
| 请求限制 | 防 DDoS、限速 |
| Gzip 压缩 | 减少传输体积 |
| 缓存 | 静态资源缓存 |
#2. Uvicorn 高级运行
#2.1 单机多 Worker
# 启动 4 个 worker(推荐:CPU 核心数 × 2 - 1)
uvicorn main:app \
--host 0.0.0.0 \
--port 8000 \
--workers 4 \
--loop uvloop \
--http httptools \
--proxy-headers \
--forwarded-allow-ips='*'#2.2 Gunicorn + Uvicorn Workers
# 安装
pip install gunicorn[gevent]
# gunicorn.conf.py
import multiprocessing
bind = "0.0.0.0:8000"
workers = multiprocessing.cpu_count() * 2 + 1 # 核心数 × 2 + 1
worker_class = "uvicorn.workers.UvicornWorker"
keepalive = 65
timeout = 30
graceful_timeout = 30
max_requests = 10000
max_requests_jitter = 1000 # 随机打散重启时间
accesslog = "-"
errorlog = "-"
loglevel = "info"
# 启动
gunicorn -c gunicorn.conf.py main:app#3. Nginx 配置
#3.1 基础反向代理配置
# /etc/nginx/conf.d/daoman.conf
upstream daoman_api {
server 127.0.0.1:8000;
keepalive 32;
}
server {
listen 80;
server_name daomanpy.com www.daomanpy.com;
# HTTP 自动跳转 HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name daomanpy.com www.daomanpy.com;
# SSL 证书(Let's Encrypt 自动续期)
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
# 安全头
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# Gzip 压缩
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_proxied any;
gzip_types text/plain text/css application/json application/javascript
application/xml application/xml+rss text/javascript;
# 限流(防止 DDoS)
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=addr:10m;
# 主 API 代理
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
limit_conn addr 10;
proxy_pass http://daoman_api;
proxy_http_version 1.1;
proxy_set_header Connection "";
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 X-Forwarded-Host $host;
proxy_connect_timeout 60s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
client_max_body_size 10M;
}
# 静态文件(直接由 Nginx 提供)
location /static/ {
alias /var/www/static/;
expires 30d;
add_header Cache-Control "public, immutable";
}
# WebSocket(长连接)
location /ws/ {
proxy_pass http://daoman_api;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 86400;
}
# 健康检查(Nginx 直接响应,不用经过 Python)
location /health_nginx {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
# 文档
location /docs {
proxy_pass http://daoman_api;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
location /openapi.json {
proxy_pass http://daoman_api;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}#4. Systemd 管理服务
#4.1 Uvicorn 服务单元
# /etc/systemd/system/daoman-api.service
[Unit]
Description=Daoman FastAPI Service
After=network.target
Wants=network-online.target
Requires=postgresql.service redis.service
[Service]
Type=notify
User=www-data
Group=www-data
WorkingDirectory=/opt/daoman
Environment="ENV=production"
EnvironmentFile=/opt/daoman/.env
ExecStart=/opt/daoman/venv/bin/gunicorn \
-c /opt/daoman/gunicorn.conf.py \
main:app
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutStopSec=5
PrivateTmp=true
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target#4.2 服务管理命令
# 重新加载配置
sudo systemctl daemon-reload
sudo systemctl restart daoman-api
# 查看状态和日志
sudo systemctl status daoman-api
sudo journalctl -u daoman-api -f --lines=50
# 开机自启
sudo systemctl enable daoman-api#5. 完整生产部署流程
# 1. 服务器安装 Nginx、PostgreSQL、Redis
sudo apt update && sudo apt install nginx postgresql redis-server
# 2. 配置 PostgreSQL
sudo -u postgres psql
CREATE DATABASE myapp;
CREATE USER appuser WITH ENCRYPTED PASSWORD 'your_password';
GRANT ALL PRIVILEGES ON DATABASE myapp TO appuser;
# 3. 部署代码
git clone https://github.com/your-repo/daoman-api.git /opt/daoman
cd /opt/daoman
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
# 4. 配置环境变量
cp .env.production.example .env
nano .env # 填写真实密钥和数据库连接
# 5. 初始化数据库
alembic upgrade head
# 6. 配置 Nginx
sudo cp nginx/daoman.conf /etc/nginx/conf.d/
sudo nginx -t # 测试配置
sudo systemctl reload nginx
# 7. 启动服务
sudo systemctl enable --now daoman-api nginx
# 8. 查看最终效果
curl https://daomanpy.com/health_nginx
curl https://daomanpy.com/docs#6. 小结
生产部署架构:
用户 → Nginx (SSL 终结, 限流, 静态文件) → Uvicorn Workers (Python)
↓
PostgreSQL ← Redis💡 记住:Nginx 负责接收所有外部流量,Uvicorn 只需监听本地端口。静态文件交给 Nginx 处理,Python 只处理动态请求。
🔗 扩展阅读

