Nginx 通过 upstream 定义 Python 后端服务池、proxy_pass 转发请求,并透传 X-Real-IP 等关键头实现反向代理与负载均衡,支持权重、ip_hash、least_conn 等策略及被动健康检查。

Nginx 配合 Python 应用实现反向代理与负载均衡,核心在于 upstream 定义后端服务池 + proxy_pass 转发请求 + 关键头透传与健康检查机制。这不是简单“转发”,而是构建可伸缩、容错、真实可用的服务网关。
upstream 模块定义 Python 后端服务池
必须显式声明一组运行中的 Python 实例(如 Flask/FastAPI/Uvicorn 服务),每个实例监听不同端口或 IP:
upstream python_app {
server 127.0.0.1:8000 weight=3 max_fails=2 fail_timeout=10s;
server 127.0.0.1:8001 weight=1 max_fails=2 fail_timeout=10s;
server 192.168.1.100:8000 backup; # 故障时启用备用节点
}-
weight控制流量比例(例如 3:1),适合性能不均的机器 -
max_fails和fail_timeout构成被动健康检查:连续失败 2 次后,10 秒内不再发请求 -
backup标记仅在其他节点全不可用时才参与调度
注意:Python 服务需已就绪(如
uvicorn main:app --host 0.0.0.0 --port 8000),且能独立响应curl http://localhost:8000/health。
反向代理配置要透传真实客户端信息
仅写 proxy_pass 不够,后端 Python 应用若依赖用户 IP 或协议类型,必须手动设置请求头:
立即学习“Python免费学习笔记(深入)”;
调用 Cutout.Pro 视觉处理 API 进行背景移除、人像抠图和照片增强,支持文件上传与图片 URL 输入。
location / {
proxy_pass http://python_app;
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_set_header X-Forwarded-Port $server_port;
}-
X-Forwarded-For是关键,Flask 中可通过request.headers.get('X-Forwarded-For', request.remote_addr)获取真实 IP - 若 Python 应用启用了 HTTPS 重定向逻辑(如
if not request.url.startswith("https")),X-Forwarded-Proto就必不可少
支持多种调度策略适配不同场景
Nginx 内置算法可按需切换,无需改代码:
- 轮询(默认):请求依次分发,适合同构实例
- 权重(weight):给高配机器更多流量,如上例中 8000 端口承担约 75% 请求
- ip_hash:同一客户端 IP 始终路由到同一后端,适用于有状态会话(如某些 Session 存本地内存的旧应用)
- least_conn:优先发往当前连接数最少的节点,更适合长连接或推理类 Python 服务(如 LLM API)
只需在 upstream 块中添加对应指令即可:
upstream python_app {
ip_hash; # 或 least_conn;
server 127.0.0.1:8000;
server 127.0.0.1:8001;
}验证与可观测性不能跳过
部署后务必验证三点:
- 执行
curl -I http://your-domain.com检查响应头是否含Server: nginx,确认代理生效 - 多次请求
/,用curl http://your-domain.com | grep "Server-"观察是否交替返回Server-A/Server-B - 主动停掉一个后端(如
kill -9 $(pgrep -f "uvicorn.*8000")),再持续请求,确认 10 秒内自动剔除且无 502 错误
Nginx 日志(/var/log/nginx/access.log)里每条记录的 $upstream_addr 字段,能直接看到本次请求实际打到了哪个 Python 实例,是排查调度问题的第一手依据。
不复杂但容易忽略细节

















