weight是加权轮询的相对权重值,非百分比;如weight=1与weight=3则流量比约1:3,但需健康节点、无积压、无hash策略干扰,且受响应时间影响可能导致偏差超20%。

nginx upstream 里 weight 参数到底怎么影响请求分发
weight 不是百分比,而是加权轮询里的相对权重值。比如 server a:8000 weight=1 和 server b:8001 weight=3,实际流量比接近 1:3,但前提是所有 server 健康、无连接积压、无 sticky 会话干扰。
- weight 只在 upstream 模块启用
least_conn或默认轮询(round_robin)时生效;如果用了ip_hash或hash $request_uri,weight 会被忽略 - 真实流量比例受后端响应时间影响很大:慢节点即使 weight 小,也可能因连接堆积被跳过,导致实际切分偏差超 20%
- 建议灰度初期用
weight=1和weight=9而非weight=10和weight=90,避免整数溢出或配置加载异常(某些旧版 nginx 对 weight 总和 > 65535 有截断)
如何让灰度流量只打到指定 Python 应用实例
光靠 weight 不够,必须配合健康检查 + 请求特征隔离,否则登录态、缓存、数据库读写不一致会立刻暴露。
- 在 upstream 块里为灰度实例单独加
down标志或用backup,上线前先手动置为 active - 用
map指令识别灰度标识:比如从 cookie 里提取gray=1,或从 headerX-Gray-Version读取,再通过proxy_pass http://$upstream_name动态路由 - Python 应用侧需识别并记录
X-Forwarded-For和X-Real-IP,避免日志里全是 nginx 内网 IP;Django 的SECURE_PROXY_SSL_HEADER或 FastAPI 的TrustHeadersMiddleware都得配对启用
502 Bad Gateway 出现时,怎么快速定位是灰度配置问题还是应用崩了
先看 nginx error log 里带 upstream prematurely closed connection 还是 connect() failed (111: Connection refused) —— 前者大概率是 Python 进程卡住或超时,后者才是 upstream 列表里地址/端口写错或服务根本没起来。
- 执行
curl -I http://localhost:8000/healthz直连各 Python 实例,确认200 OK且响应时间 health_check 指令,它默认只 check TCP 连通性 - 检查
proxy_read_timeout是否小于 Python 应用的超时设置(如 uvicorn 的--timeout-keep-alive),常见坑是 nginx 等 60s 断开,而 Python 还在处理长请求 - 用
nginx -t验证配置后,务必nginx -s reload,别用restart——热重载失败时进程还在,但新配置未生效,现象就是部分请求 502、部分正常
Python 日志里看不到真实客户端 IP,只看到 nginx 内网地址
这是最常被忽略的链路断裂点。nginx 默认不会透传原始 IP,Python 应用拿到的 request.client.host 是 nginx 的 local IP。
- 必须在 nginx 的
location块里加proxy_set_header X-Real-IP $remote_addr和proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for - Python 侧不能直接信
X-Forwarded-For,要结合trusted_hosts白名单(如只信任10.0.0.0/8内网段),否则伪造 header 会导致日志污染或安全漏洞 - Flask 用户注意:
request.remote_addr默认不解析 header,得用request.environ.get('HTTP_X_REAL_IP');Django 则依赖USE_X_FORWARDED_HOST = True和SECURE_PROXY_SSL_HEADER
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











