深色模式
负载均衡误配排查
摘要:负载均衡"看起来正常"但流量异常,通常是健康检查、权重、超时或会话保持的误配。本文从后端列表状态入手,逐项核对配置,并说明为什么健康节点会被误摘。
适用环境
bash
nginx -v 2>/dev/null
which haproxy curl 2>/dev/null
curl -V | head -11
2
3
2
3
排障步骤
第 1 步:确认后端节点是否被判为健康
bash
# nginx 商业版/plus 有 status 接口;开源版看配置 + 日志
grep -rn 'upstream' -A 12 /etc/nginx/conf.d/ 2>/dev/null | head -40
grep -iE 'upstream|no live|connect\(\) failed' /var/log/nginx/error.log | tail -201
2
3
2
3
云 LB 则在控制台查看后端健康状态,同时核对健康检查配置。
第 2 步:核对健康检查配置
常见配置项:协议、路径、端口、期望状态码、间隔、超时、成功/失败阈值。
bash
grep -rniE 'health|check|probe' /etc/nginx/conf.d/*.conf 2>/dev/null
curl -sS -o /dev/null -w '%{http_code}\n' http://<后端IP>:<端口>/health1
2
2
健康检查端点返回非 200 会被摘除
应用返回 301/302(未登录跳转)或 403 时,很多健康检查判定为失败。健康检查路径应返回明确 200 且不做鉴权。
健康检查间隔过短会打满日志与连接
每秒探测一次、阈值 1 次失败即摘除,会在 GC 停顿或发布重启的瞬间把整个集群摘空。
第 3 步:检查权重与流量分配
bash
grep -rn 'weight' /etc/nginx/conf.d/*.conf 2>/dev/null1
权重配置错误会造成流量倾斜
weight 写成 0 的节点不接流量;只给灰度实例配了超大权重会把全量流量打过去。变更权重后必须立刻核对请求分布。
第 4 步:核对超时配置
bash
grep -rniE 'proxy_read_timeout|proxy_connect_timeout|proxy_send_timeout|timeout' /etc/nginx/conf.d/*.conf 2>/dev/null1
LB 超时必须大于后端应用的正常处理时间,否则慢接口会被 LB 提前断开,表现为客户端收到 504。
第 5 步:会话保持与长连接
bash
grep -rniE 'ip_hash|sticky|keepalive' /etc/nginx/conf.d/*.conf 2>/dev/null1
开启会话保持会让负载不均
基于源 IP 的哈希在 NAT 出口环境下会把大量用户算作同一来源,导致流量集中到单个节点。
第 6 步:逐台后端直连验证
bash
for ip in <ip1> <ip2> <ip3>; do
echo -n "$ip: "
curl -sS -m 3 -o /dev/null -w '%{http_code} %{time_total}\n' -H 'Host: <域名>' http://$ip:<端口>/health
done1
2
3
4
2
3
4
逐个绕过 LB 直连后端,能立刻区分是 LB 配置问题还是某台后端自身问题。
验证
bash
curl -sS -o /dev/null -w 'code=%{http_code} total=%{time_total}\n' http://<LB地址>/health
tail -f /var/log/nginx/access.log | awk '{print $NF}' | sort | uniq -c1
2
2
常见坑
只通过 LB 域名测试无法定位
必须同时验证"经 LB"和"直连后端"两条路径,否则无法判断故障在哪一侧。
后端摘除后容量不足
健康检查误摘掉一半节点,剩余节点承接全量流量又被压垮,形成级联失败。摘除过多时应同步扩容。
修改配置未 reload
nginx -s reload 前务必 nginx -t 校验语法,配置错误会导致 reload 失败并继续用旧配置。
直接删除后端节点配置止血
会让剩余节点承接全量流量引发过载。应先确认容量,再按灰度方式调整。