NGINX 四层上游健康检查模块实战`ngx_stream_upstream_hc_module`
一、模块简介
ngx_stream_upstream_hc_module
自 NGINX 1.9.0(2015-08-04)起提供,对商业版用户开放。它让 NGINX 在Stream(四层)场景下,周期性地对定义在共享内存(zone
)中的上游服务器组执行健康检查,自动剔除不健康节点,从而提升可用性与故障自动恢复能力。
-
核心功能
- 定期对每台后端服务器发起 TCP 或 UDP 健康探测
- 依据探测结果将服务器置为 up、down 或 checking 状态
- 客户端连接不会转发给
down
或checking
状态的服务器 - 支持自定义请求/响应内容校验(
match
块)
-
依赖条件
- NGINX 编译需启用
--with-stream
(包含此模块) - 上游组必须声明
zone
(共享内存) - 该模块仅在商业订阅版中可用
- NGINX 编译需启用
二、核心指令
1. health_check
启用对当前 proxy_pass
指向的上游组进行周期性健康检查。
server {listen 12346;proxy_pass tcp; # tcp 是 upstream 组名health_check [参数];
}
-
常用参数
interval=time
:两次健康检查间隔,默认 5sjitter=time
:随机延迟,避免“雪崩”检查,默认无fails=n
:连续失败次数,达到后置为 down,默认 1passes=n
:连续成功次数,达到后置为 up,默认 1mandatory [persistent]
:启动时强制先执行检查,检查完成前视为checking
;persistent
重载后保留上次状态match=name
:引用match
块名,进行自定义内容校验port=n
:使用不同端口进行健康检查(1.9.7+),默认同服务器端口udp
:使用 UDP 而非 TCP(1.9.13+)
2. health_check_timeout
health_check_timeout 5s;
- 覆盖内部探测的超时时间,默认同
proxy_timeout
。
3. match
定义自定义探测中客户端发送内容与服务器应答内容的匹配规则。
match <name> {send "<请求报文>";expect <literal|string|~regex>;
}
send
:向服务器发送的原始字节串,可含\x
十六进制expect
:字符串或正则(前缀~
/~*
),检查服务器返回数据- 只有同时满足 TCP/UDP 可连通、发送成功、回复匹配、未超时四个条件,才算一次成功。
三、配置示例
3.1 TCP 连接检查(默认)
# 定义上游
upstream tcp {zone upstream_tcp 64k;server b1.example.com:12345 weight=5;server b2.example.com:12345 fail_timeout=5s slow_start=30s;server 192.0.2.1:12345 max_fails=3;server backup1.example.com:12345 backup;server backup2.example.com:12345 backup;
}# 入口监听
server {listen 12346;proxy_pass tcp;health_check; # 每 5s 尝试 TCP 握手,失败即 down
}
3.2 UDP 简单探测
upstream dns_upstream {zone dns_zone 64k;server dns1.example.com:53;server dns2.example.com:53;server dns3.example.com:53;
}server {listen 53 udp;proxy_pass dns_upstream;health_check udp; # 发送默认 “nginx health check”,检查无 ICMP Unreachable
}
3.3 自定义内容校验(HTTP 响应)
upstream backend {zone backend_zone 10m;server 127.0.0.1:12345;
}# 定义测试 “match” 块
match http_check {send "GET / HTTP/1.0\r\nHost: localhost\r\n\r\n";expect ~ "200 OK";
}server {listen 12346;proxy_pass backend;health_check match=http_check;health_check_timeout 3s;
}
- 仅检查 proxy_buffer_size 字节内内容,匹配
200 OK
即通过。
四、工作原理与状态转换
-
启动阶段
- 若未指定
mandatory
:默认将所有服务器视为up
,立即对客户端提供服务,同时后台发起首轮检查 - 若指定
mandatory
:所有服务器初始为checking
,待首轮检查通过后才变up
- 若未指定
-
周期检查
- 每隔
interval ± jitter
发起一次健康探测(TCP 握手或 UDP 探测) - 检测过程可发送自定义 payload(
match.send
)并匹配响应(match.expect
)
- 每隔
-
状态决策
- 连续失败 ≥
fails
→ 标记为down
- 连续成功 ≥
passes
→ 从down
或checking
转为up
- 在
down
或checking
状态下,不向该服务器转发客户端连接
- 连续失败 ≥
-
恢复与持久化
- 加入
persistent
后,reload 保留上次健康状态 - 商业版可结合
state
将状态写入文件,实现跨进程、跨版本持久化
- 加入
五、最佳实践与注意事项
-
合理选择间隔与超时
interval
不宜过短(避免探测风暴),也不宜过长(影响故障感知)health_check_timeout
应小于interval
一半,确保及时判定
-
使用
jitter
避免同步探测- 大规模部署时,加上
jitter
防止所有实例同时发起探测引起网络抖动
- 大规模部署时,加上
-
精细化
match
校验- TCP 检查只验证握手;若需检查应用层可用性,务必使用
match
自定义协议逻辑
- TCP 检查只验证握手;若需检查应用层可用性,务必使用
-
备份与故障切换
- 将高优先级主节点置为普通
server
,次级节点加backup
;当所有主节点 down 时自动切换
- 将高优先级主节点置为普通
-
持久化与重载
- 启用
mandatory persistent
+state
文件,reload 后快速恢复上次状态,避免“空窗期”
- 启用
六、小结
ngx_stream_upstream_hc_module
为 NGINX 四层代理注入“运维智能”,通过自动化健康检查与自定义探测逻辑,可大幅提升后端可靠性与故障恢复速度。对商业用户而言,结合共享 zone
、state
持久化、persistent
、slow_start
等功能,能实现企业级零停机灰度发布与多机房流量管理。
动手即用:在您的 Stream 配置中加上 zone
+ health_check
,让 NGINX 替您监测后端,自动剔除故障节点,确保业务高可用!