两台上游停了一台,Nginx 仍按轮询转发,每三次请求就有一个 502,日志里 connect refused。第一次遇到会往复杂处想,其实漏掉的多是个小前提。
upstream api_backend {
server 10.0.1.11:8080 max_fails=2 fail_timeout=30s;
server 10.0.1.12:8080 max_fails=2 fail_timeout=30s;
proxy_next_upstream error timeout http_502;
}
默认的被动检查要等请求失败才标记,max_fails 和 fail_timeout 没配时容错很短。没有主动健康检查,恢复和摘除都靠真实流量试。这一点先确认清楚,后面就不用反复试。
「上游健康检查」这个问题文档写得含糊,实际行为以当前版本为准,别照旧版本的结论套。把复现步骤压到三条以内,交给同事也能跑出来,才算真的定位清楚。
改动写完就同步给同事,下一个人踩同一个坑,成本还是你的。验证用真实数据走一遍,测试数据太干净,边界情况根本碰不到。
能分两步做的操作就别合成一步,中间看一眼返回值,出问题好判断。
具体做法是,在 upstream 里给每台配 max_fails=2 fail_timeout=30s;加 proxy_next_upstream error timeout 让失败请求换一台;有条件的用 openresty 或模块做主动探测;用循环请求统计 502 比例 验证摘除是否生效。
改完照着核一遍,挂掉一台后连续 100 次请求 502 为 0 恢复后流量重新分到两台。
