nginx通过被动健康检查实现异常节点自动隔离,需配置upstream的max_fails和fail_timeout、proxy_next_upstream重试策略及proxy_connect/send/read_timeout超时参数协同生效。

配置带故障感知的 upstream
在 http 块中定义 upstream,并为每个后端显式设置失败判定规则:
- max_fails=2:连续失败 2 次就标记该节点为不可用(微服务建议值,敏感链路可设为 1)
- fail_timeout=15s:被标记后,15 秒内不再向它转发新请求;超时后会尝试一次新连接,成功则恢复
- 可选加 weight 区分处理能力,或 backup 标记灾备节点(仅主节点全挂时启用)
示例:
upstream order_service {server 10.0.3.10:8080 max_fails=2 fail_timeout=15s weight=3;
server 10.0.3.11:8080 max_fails=2 fail_timeout=15s;
server 10.0.3.12:8080 backup;
}
启用请求重试与错误码转发
仅把节点“下线”不够,当前请求还得能转给别的节点。这靠 proxy_next_upstream 实现:
- 在 location 块中添加:proxy_next_upstream error timeout http_500 http_502 http_503 http_504
- 这样遇到连接失败、超时、或后端返回这些 5xx 状态码时,Nginx 就自动换下一个可用节点重试
- 建议加上 proxy_next_upstream_tries 2,限制最多重试 1 次(避免反复冲击)
配齐超时参数防拖垮
没有合理超时,一个慢节点就能拖住整个 worker 进程。关键三项要设:
- proxy_connect_timeout 3s:建连最多等 3 秒
- proxy_send_timeout 8s:发请求体超时,通常略短于读超时
- proxy_read_timeout 10s:等后端响应头/数据,按业务接口平均耗时设(如导出类可放宽)
这些值要明显小于后端自身超时,才能确保 Nginx 主动放弃,而非傻等。
验证是否真起作用
改完配置别只 reload 就完事,要动手验证:
- 执行 nginx -t && nginx -s reload
- 停掉一台后端(比如 systemctl stop app-order),持续 curl 请求
- 观察是否全部落到其余节点——用 tcpdump -i any port 8080 抓包最直观
- 查 /var/log/nginx/error.log,搜 "upstream failed" 和 "no live upstreams",前者说明触发重试,后者说明所有节点都被踢光(阈值可能太严)











