weight参数未生效是因为nginx默认使用纯轮询策略,而weight仅在加权轮询(即默认轮询启用weight)或least_conn下有效,且需排除ip_hash等会话绑定指令、所有server均配置weight、版本≥1.9.1、配置语法正确。

Nginx 的 upstream 块本身不自动启用加权轮询,weight 参数在默认轮询策略下完全无效——必须显式选择策略或确认无冲突指令,否则所有后端一律均等分流。
为什么 weight 参数没生效?
最常见原因是 Nginx 默认使用纯轮询(round-robin),而 weight 只在加权轮询或 least_conn 下起作用。但加权轮询不是独立策略名,它只是轮询的“带权重变体”,需同时满足:
-
upstream块里没启用ip_hash、hash $request_uri等会话绑定指令——它们强制单个客户端固定到某台后端,权重自然失效 - 每个
server行都明确写了weight=,例如server 127.0.0.1:8001 weight=3;,不能只写一部分 - Nginx 版本 ≥ 1.9.1;老版本(如 1.4.x)即使写了
weight也降级为均等轮询 - 配置 reload 前用
nginx -t验证语法,避免因格式错误导致整段upstream未加载
如何验证流量是否按 weight 分流?
别依赖肉眼刷新页面,真实分布需要可观测数据:
- 在
location块里加proxy_set_header X-Backend $upstream_addr;,后端 Python 应用(Flask/FastAPI)从请求头读取并记录,或直接返回该 header 方便 curl 观察 - 启用 Nginx access log 的 upstream 地址字段:
log_format main '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$upstream_addr"'; - 用
curl -I http://your-domain/health快速发起 20+ 次请求,统计响应头中X-Backend或日志里各后端 IP 出现频次,看是否接近权重比(如 3:2)
Python 应用怎么拿到真实用户 IP?
这不是 Python 框架的问题,是 Nginx 代理链没透传。如果只配了 proxy_pass,request.client.host(FastAPI)或 request.remote_addr(Flask)拿到的全是 Nginx 自己的 IP。
必须在 location 块里补这三行:
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;
然后 Python 侧读取 X-Forwarded-For 头(注意:需信任代理,不能直接暴露给公网);FastAPI 可用 request.headers.get("X-Forwarded-For"),Flask 用 request.headers.get("X-Forwarded-For"),并确保启动时加 trusted_hosts=["your-nginx-ip"] 类似防护。
健康检查和故障转移容易被忽略
max_fails 和 fail_timeout 不是可选参数,而是决定高可用底线的关键:
-
max_fails=2 fail_timeout=30s表示:连续 2 次失败(超时或 5xx)后,Nginx 将该后端标记为不可用,30 秒内不再转发请求 - 必须配合
proxy_next_upstream error timeout http_500;才能触发重试;否则失败请求直接 502 给用户 - Python 应用要提供轻量
/health接口(如 FastAPI 的@app.get("/health")返回 200),Nginx 可用health_check指令主动探测(需商业版或开源版 + Lua 模块)
权重再精细,后端挂了却不自动剔除,高可用就只剩空壳。真正上线前,务必手动 kill 一个 Python 进程,观察 Nginx 日志是否停止向其发请求,并确认其余节点承接了全部流量。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











