nginx可通过被动健康检查(max_fails+fail_timeout)实现主备自动切换,主节点故障后流量转向低权重备用节点;nginx plus支持主动健康检查(health_check),更及时可靠;开源方案可借助第三方模块或外部脚本补充。

通过 Nginx 的健康检查机制配合 upstream 模块的容错能力,可以实现后端主备节点的自动健康剔除与流量切换。核心不依赖外部脚本,而是利用 nginx-plus 的高级功能或开源版 Nginx 配合合理配置+简单探测逻辑来达成“主活则用、主挂则切备”的效果。
使用开源 Nginx + 被动健康检查(推荐轻量场景)
开源版 Nginx 本身不支持主动健康检查(如定期发 HTTP 请求探测),但支持基于请求结果的被动健康检查(max_fails + fail_timeout)。适用于主备结构中主节点故障后自动降级到备用节点的场景:
-
配置示例:在
upstream中为节点设置不同权重,并启用失败计数
upstream backend {
server 192.168.1.10:8080 weight=10 max_fails=3 fail_timeout=30s; # 主节点
server 192.168.1.11:8080 weight=1 max_fails=0; # 备节点(默认不参与失败统计)
}-
max_fails=3表示连续 3 次请求失败(如超时、5xx、连接拒绝)后,Nginx 将该节点标记为不可用 -
fail_timeout=30s表示在此时间内不再向该节点转发请求;30 秒后会尝试恢复探测 - 备节点设
weight=1且max_fails=0,表示它始终可用、不因失败被剔除,但默认几乎不被选中(因权重远低于主) - 当主节点连续失败 3 次,Nginx 自动将流量全部导向备节点,实现“软主备切换”
升级到 Nginx Plus(官方商业版)实现主动健康检查
Nginx Plus 原生支持主动健康检查(health_check 指令),可定时对后端发送 HEAD/GET 请求,根据响应状态码、响应时间等判断节点健康状态,更可靠、更及时:
- 配置示例(需 Plus 许可)
upstream backend {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
<p>location / {
proxy_pass <a href="https://www.php.cn/link/65b5b8d1f89bf53a5713bc3afdd83e9e">https://www.php.cn/link/65b5b8d1f89bf53a5713bc3afdd83e9e</a>;
health_check interval=5 fails=2 passes=2 uri=/health;
}</p>-
interval=5:每 5 秒探测一次 -
fails=2:连续 2 次失败即剔除节点 -
passes=2:连续 2 次成功才恢复节点 -
uri=/health:后端需提供该健康接口,返回 200 表示健康 - Plus 还支持
match自定义响应匹配规则(如校验 body 内容),适合严格场景
开源方案补充:用第三方模块或外部脚本兜底
若必须用开源 Nginx 且需主动探测能力,可考虑:
- nginx_upstream_check_module:第三方补丁模块,编译进 Nginx 后支持类似 Plus 的主动健康检查(需自行维护编译)
- Consul + nginx-upsync-module:通过服务发现动态更新 upstream,配合 Consul 的健康检查自动增删节点(适合微服务架构)
-
简单 shell 脚本 + reload:定时 curl 探测,异常时生成新 upstream 配置并
nginx -s reload(注意 reload 有轻微性能抖动,不建议高频触发)
关键注意事项
无论哪种方式,都需关注以下细节才能稳定主备切换:
- 后端健康接口要轻量、高可用:避免健康检查自身成为瓶颈或单点故障(例如不要依赖数据库)
- fail_timeout 设置要合理:太短易误剔(网络抖动),太长导致故障恢复慢;建议设为 2–5 倍平均响应时间
- 主备节点应部署在不同物理机/可用区,避免单点基础设施故障同时影响两者
- 客户端需配合短连接 + 重试机制:Nginx 剔除节点是秒级的,但长连接可能仍维持旧路径,建议应用层做失败重试
-
开启
proxy_next_upstream:让单次请求在上游失败时自动重试其他节点(含备节点),提升成功率











