nginx负载均衡健康检查需区分被动响应与主动探测:proxy_next_upstream实现基于请求失败的被动检查,nginx_upstream_check_module支持定时http/tcp主动探测,须适配防火墙并接入监控闭环。

Nginx 负载均衡中的健康检查不能靠“连得上就认为健康”,必须分清被动响应和主动探测两种逻辑,否则容易漏判、误判或延迟发现故障。
用 proxy_next_upstream 实现基础被动检查
这是开源 Nginx 原生支持的方式,无需额外模块,依赖真实请求失败来动态调整后端状态:
-
在 upstream 中为每个 server 明确配置
max_fails和fail_timeout:-
max_fails=3表示连续 3 次失败(连接拒绝、超时、5xx 等)才标记为不可用 -
fail_timeout=30s表示该节点被屏蔽 30 秒,之后自动试探恢复
-
-
在 location 块中启用
proxy_next_upstream,定义哪些响应算“失败”并触发重试:- 推荐组合:
error timeout http_500 http_502 http_503 http_504 - 避免加入
http_404或http_403—— 这些通常是业务返回,不是后端异常
- 推荐组合:
注意:这个机制不发心跳,没请求就不会检查;节点刚启动但服务未就绪时,流量仍会打过去。
用 nginx_upstream_check_module 实现主动探测
要真正实现“定时探活”,需使用这个广泛兼容的第三方模块(常见于 OpenResty 或手动编译版本):
-
编译安装后,在 upstream 块中添加
check指令:-
check interval=3 rise=2 fall=5 timeout=1 type=http -
check_http_send "HEAD /health HTTP/1.0\r\n\r\n"发轻量请求 -
check_http_expect_alive http_2xx http_3xx只把 2xx/3xx 当健康
-
-
关键细节:
-
rise=2防止偶发抖动导致误恢复 -
fall=5避免单次丢包就下线 - 必须配
default_down=true,防止 Nginx 启动时把未就绪节点当健康节点
-
探测路径建议用专用接口(如
/actuator/health或/ready),不走业务链路。
适配防火墙与网络策略
很多“假死”不是后端真挂了,而是健康检查被中间设备拦截:
- 先排查拦截层:是 iptables 丢包?安全组限速?还是 WAF 拦截了
/health路径? - 若无法改防火墙,可调整探测行为:
- 改用
type=tcp检查端口连通性,绕过路径和头校验 - 把
interval放宽到 10–30 秒,降低探针频率 - 去掉
check_http_expect_alive http_503,避免 GC 导致的短暂 503 被误判
- 改用
- 后端应暴露独立健康端点,并确保该路径在防火墙白名单中显式放行。
暴露状态页并接入监控闭环
健康检查的价值取决于能否及时感知和干预:
- 启用
stub_status或模块自带的/status接口,实时查看各节点state(up/down/unhealthy)、fails、rise等指标 - 将这些指标接入 Prometheus 或 Zabbix,设置告警规则(如连续 3 次
fall触发通知) - 记录 access log 时开启
$upstream_addr和$upstream_http_x_backend_status,便于回溯具体哪次请求被转发到哪个后端及结果
不复杂但容易忽略。











