Nginx双机热备需以SLA为目标构建闭环保障机制,涵盖细粒度健康检查(如/healthz)、全栈监控(接入/转发/业务层)、防脑裂雪崩的自动恢复策略及切换后有效性验证。

在 Nginx 双机热备(如基于 Keepalived 实现 VIP 漂移)环境中,仅靠主备切换本身无法保障服务质量——服务是否真正可用、响应是否达标、故障是否被及时发现,都需要主动监控与闭环保障机制。关键不在于“有没有备机”,而在于“能不能持续提供符合 SLA 的服务”。
健康检查不能只看进程和端口
默认的 Keepalived TCP_CHECK 或 Nginx 自身的 health_check(在 upstream 中)若仅检测 80/443 端口是否通,容易漏判真实业务异常。例如:Nginx 进程存活但后端全部超时、证书过期导致 HTTPS 握手失败、或返回 502/503 却仍能接受 TCP 连接。
- 对 upstream 块启用细粒度健康检查:
health_check interval=3 fails=2 passes=2 uri=/healthz match=ok;
配合自定义/healthz接口(返回 200 + JSON {"status":"ok"}),该接口需校验上游服务连通性、关键依赖(如 Redis、DB)、资源水位(如内存使用率 < 90%) - Keepalived 使用 HTTP_GET 替代 TCP_CHECK,在 vrrp_script 中调用 curl 检查业务路径,并设置非零退出码触发降权
- 避免检查路径暴露敏感信息,建议独立路由、IP 白名单或带签名 token
监控指标要覆盖“请求链路全栈”
双机热备下易陷入“VIP 能 ping 通就等于服务正常”的误区。实际需分层采集并关联告警:
-
接入层:Nginx 的
stub_status(Active connections、Requests/sec)、5xx 错误率(尤其 502/504)、upstream_response_time P95/P99 -
转发层:Keepalived 状态(MASTER/BACKUP)、VIP 绑定状态、vrrp 通告延迟(
ip -s link show eth0查看 multicast 丢包) - 业务层:/healthz 接口响应时间与状态、核心 API 的成功率与耗时(可通过 Nginx log_format 记录 $upstream_http_x_request_id 和 $upstream_response_time 后对接链路追踪)
- 所有指标统一打标(如 instance=nginx-web-01, role=master)便于故障时快速定位是节点问题还是切换问题
自动恢复策略需设防“脑裂”与“雪崩”
热备切换不是终点,而是保障连续性的起点。无约束的自动切回或频繁切换会加剧风险:
- Keepalived 配置
nopreempt(仅 BACKUP 节点配置),避免 MASTER 恢复后立即抢主造成连接中断;主恢复后通过脚本人工确认再启用 preemption - 设置切换冷却期:vrrp_script 中加入 last_switch_time 文件记录,两次切换间隔强制 ≥ 300 秒,防止瞬时抖动引发震荡
- Nginx upstream 配置
max_fails=3 fail_timeout=30s,但 fail_timeout 不宜过短(如 5s),否则短暂网络抖动即触发摘除,放大负载压力 - 备用节点在接管 VIP 后,启动轻量级预热脚本(如并发 10 次 curl 本地 /healthz + 关键 API),确认服务就绪再开放流量
故障复盘必须包含“切换有效性验证”
每次主备切换后,不能止于“服务恢复”,需验证切换是否真正提升了可用性:
- 比对切换前后 5 分钟的 error_log:是否仍有大量 upstream timed out?是否因后端未同步导致新主节点连接旧配置?
- 检查 Nginx access_log 中 client_addr 是否为真实用户 IP(确认 real_ip_header 配置在切换后仍生效,避免日志失真)
- 模拟客户端从不同地区发起请求,验证 DNS 缓存、CDN 回源、以及客户端 TCP 连接重试行为是否与预期一致
- 将切换事件写入 CMDB 变更日志,关联监控告警、日志关键字、变更操作人,形成可追溯的服务质量证据链


















