nginx 无感知切换需两层协同:upstream 层通过 max_fails、proxy_next_upstream 等实现后端故障自动剔除与重试;keepalived 层通过健康检查与 vip 漂移保障 nginx 自身高可用,二者缺一不可。

要让 Nginx 在后端节点故障时实现业务无感知切换,关键不是“等它挂了再反应”,而是提前建立可探测、可判定、可重试、有兜底的完整链路。核心在于两层协同:Nginx 自身对后端服务的被动健康感知与请求重试机制(upstream 层),以及 Keepalived 对 Nginx 进程/服务级的主动守护与 VIP 漂移(入口层)。单靠其中一层,都做不到真正无感。
upstream 内部自动剔除 + 请求重试
这是第一道防线,处理后端应用服务器宕机、响应超时或返回错误码等常见问题:
- 在
upstream块中为每个 server 设置max_fails=3 fail_timeout=30s,表示连续失败 3 次后,在接下来 30 秒内不再向该节点转发新请求 - 配合
proxy_next_upstream error timeout http_500 http_502 http_503 http_504,让当前失败请求自动转给下一个健康节点;加上proxy_next_upstream_tries 3可限制最多尝试次数,防雪崩 - 用
backup标志定义灾备节点,例如server 192.168.1.99:8080 backup max_fails=2 fail_timeout=20s,它平时不参与轮询,仅当所有主节点不可用时才启用
Keepalived 守护 Nginx 入口可用性
这是第二道防线,解决 Nginx 自身崩溃、配置错误、CPU 占满、日志写满等导致整个入口失效的问题:
- Keepalived 通过自定义脚本(如
nginx_check.sh)定期检查curl -f http://127.0.0.1/health或pgrep nginx,一旦失败就降低本机优先级 - VRRP 协议基于优先级和心跳选举 MASTER,主节点降权后,备节点在 3–5 秒内接管虚拟 IP(VIP),客户端后续请求直接落到新 Nginx 实例上
- 务必关闭防火墙对 VRRP 多播(协议号 112)的拦截,否则心跳中断可能引发脑裂
验证是否真“无感知”
不能只看 VIP 能 ping 通,要模拟真实访问行为:
- 客户端持续执行:
watch -n 0.2 'curl -sI http://VIP | head -1 2>/dev/null',切换瞬间允许最多 1–2 次失败,之后必须立刻恢复HTTP/1.1 200 OK - 比对主备 access.log 的时间戳,主节点最后一条日志与备节点第一条日志间隔应 ≤1 秒
- 查
/var/log/messages中 Keepalived 状态变迁日志,确认出现BACKUP → MASTER(备机升主)和MASTER → FAULT(主机降级)完整过程
几个容易忽略但致命的细节
很多配置看着对,一压测就出问题:
- Nginx 配置文件中所有 server 地址必须保持完全一致(包括端口、路径、SSL 设置),否则 VIP 切过去后返回 502 或空白页
- keepalive 连接池建议开启(
keepalive 32),避免切换后大量重建连接冲击后端 - health 接口不能只是返回 200,要真实探测后端连通性(比如 proxy_pass 到一个健康检查 endpoint),否则服务假死无法识别
- 主备节点时间需同步(chrony),否则日志时间错乱、证书校验失败、VRRP 选举行为异常











