流量倾斜根因是配置冲突、健康状态异常、连接复用或日志盲区,修复关键在定位真实分发路径;需检查upstream是否被ip_hash等指令覆盖、weight语法是否规范(正整数、无空格)、健康检查是否静默剔除节点,并通过日志与批量请求验证实际分发比例。

流量倾斜不是权重数字没写对,而是配置、健康状态、连接复用或日志盲区共同作用的结果。修复关键在于定位真实分发路径,而不是反复调大 weight 值。
检查 upstream 是否被其他策略覆盖
加权轮询只在纯轮询模式下生效,一旦混入冲突指令,weight 就完全失效:
- 确认 upstream 块中没有 ip_hash、least_conn 或 hash $arg_id 等指令——哪怕注释掉也不行,必须整行删除
- 检查是否在 proxy_pass 中指向了另一个已定义的 upstream,而那个 upstream 实际启用了非轮询算法
- 运行 nginx -T | grep -A 15 "upstream your_name",看最终生效的配置里是否还残留冲突参数
验证 weight 写法是否符合语法规范
一个空格、换行或小数点,都会让 Nginx 忽略权重甚至报错:
- weight 必须紧贴 server 地址,中间不能有空格或换行:server 192.168.1.10:8080 weight=3; ✅,server 192.168.1.10:8080weight=3; ❌
- 权重值只能是正整数(1–65535),不支持小数、负数或 0(weight=0 表示临时下线)
- 所有 server 必须定义在同一个 upstream 块内,跨文件 include 或嵌套引用会导致部分节点权重丢失
排查健康检查导致的“静默剔除”
节点明明在配置里,却长期收不到请求?大概率已被 passive health check 标记为 unavailable:
- 查看 /var/log/nginx/error.log,搜索 "temporarily disabled" 或 "no live upstreams"
- 检查每个 server 行是否显式配置了 max_fails 和 fail_timeout;未配置时 Nginx 默认 max_fails=1 fail_timeout=10s,极易因偶发超时误剔
- 建议统一设为 max_fails=3 fail_timeout=30s,并搭配 proxy_next_upstream error timeout http_500 http_502 http_503 实现失败自动重试
用日志和批量请求验证真实分发效果
别信配置,要看实际流向。肉眼 curl 一两次毫无意义:
- 在 http 块中添加日志格式:log_format upstream_log '$remote_addr - $upstream_addr [$time_local] "$request" $status';
- 在 location 中启用:access_log /var/log/nginx/upstream.log upstream_log;
- 用脚本发起 ≥100 次去缓存请求:for i in {1..100}; do curl -H "Cache-Control: no-cache" -s http://your-domain/ | grep server_id; done
- 统计 $upstream_addr 字段出现频次,对比是否接近理论比例(如 weight=5:2 → 应约 71% : 29%)


















