nginx轮询本身不健康检查,必须配合被动(max_fails/fail_timeout+proxy_next_upstream)或主动(nginx_upstream_check_module)机制才能规避故障节点。

Nginx 轮询机制本身不执行健康监测,它只是按顺序分发请求;真正的健康监测需额外配置,否则宕机的后端仍会被轮到,导致请求失败。
轮询与健康监测是两回事
默认轮询(Round Robin)只负责调度顺序,不关心后端是否响应正常。它不会主动发心跳、不检查端口、也不验证服务可用性。只要 upstream 列表里有地址,Nginx 就会照常转发——哪怕那台服务器已关机或应用卡死。
靠 proxy_next_upstream 实现被动健康感知
这是开源 Nginx 原生支持的方式,依赖真实请求的结果来判断后端状态:
- 在 upstream 中为每台服务器设 max_fails=3 fail_timeout=30s:连续 3 次失败后,30 秒内跳过该节点
- 在 location 块中启用 proxy_next_upstream error timeout http_500 http_502 http_503 http_504:定义哪些响应算“失败”,触发重试和计数
- 注意:没流量时不会检测;新上线的服务若未就绪,首次请求仍可能打过去
用 nginx_upstream_check_module 做主动探测
要真正定时检查,必须使用这个第三方模块(常见于 OpenResty 或手动编译版本):
- 在 upstream 内添加 check interval=3 rise=2 fall=5 type=http:每 3 秒探一次,连续 2 次成功标记为健康,5 次失败才下线
- 搭配 check_http_send "GET /health HTTP/1.0\r\n\r\n" 和 check_http_expect_alive http_2xx,确保只认 2xx 响应
- 后端需提供轻量健康接口(如 /health),且该路径要在防火墙、WAF 中放行
几个容易忽略的关键点
- default_down true 必须加:防止 Nginx 启动时把尚未就绪的节点误判为健康
- 避免用 http_503 作为下线依据:K8s readiness probe 或 Spring Boot 的 /actuator/health 在启动中常返回 503,不是真故障
- 权重(weight)和健康检查可共存:比如高性能机器设 weight=3,同时配 max_fails=2,既提升调度比例,又保障容错











