Nginx+Keepalived秒级切换的关键在于Keepalived的VRRP调优与系统协同:将advert_int设为0.3~0.9秒、fail_count/rise_count统一设为2,配合HTTP健康检查、ARP参数优化及防火墙放行VRRP协议。

要让 Nginx + Keepalived 的主备切换真正达到秒级甚至亚秒级,核心不在 Nginx 本身,而在于 Keepalived 的检测逻辑和系统协同。最小化切换时间的关键,是压缩故障识别窗口,并确保切换动作不被其他环节拖慢。
缩短 VRRP 心跳间隔(advert_int)
这是最直接有效的调优项。advert_int 决定主节点发送 VRRP 通告的频率,默认为 1 秒,意味着备节点最多需等待 3 秒(3 × advert_int)才判定主失效。
- 局域网环境稳定、延迟低于 1ms:可设为 0.3~0.5 秒,故障识别窗口压缩至约 0.9~1.5 秒
- 跨机架或偶有丢包:推荐 0.7~0.9 秒,兼顾响应速度与抗抖动能力
- 不建议低于 0.2 秒:受 Linux 内核定时器精度限制,可能引发通告发送不稳定或日志报错
同步调整失败/恢复判定次数
Keepalived 默认用 3 次未收到通告判定故障(fail_count=3),该值隐式绑定 advert_int。若将 advert_int 改为 0.5 秒,但未调小 fail_count,实际检测仍需 1.5 秒——这已接近极限,再压需改判定逻辑。
- 在 vrrp_instance 块中显式设置 fail_count 2 和 rise_count 2,使故障识别缩至 2×advert_int,恢复也只需连续 2 次成功
- 避免仅依赖 rise_count 自动升主;若启用了 nopreempt,主恢复后不会抢 VIP,此时需结合 notify_backup/notify_master 脚本主动干预
用 HTTP 健康检查替代进程存活判断
只检测 nginx 进程是否运行(如 kill -0)或端口是否监听,无法反映真实业务就绪状态。例如 Nginx 正在 reload、上游全部不可达、或配置错误导致 502,进程仍在,但服务已不可用。
- 在 keepalived.conf 中定义 vrrp_script,调用 curl 访问 Nginx 暴露的 /healthz 或 /status 接口,校验 HTTP 状态码是否为 200
- 该接口应轻量、无鉴权、不依赖 upstream,且返回前确保 worker 已完成加载(可加 sleep 0.1 防 race condition)
- 脚本执行超时建议设为 1 秒以内,避免阻塞 VRRP 主循环
关闭干扰项并加固网络层收敛
即使 Keepalived 在 1 秒内完成状态切换,客户端仍可能因 ARP 缓存、防火墙拦截或内核参数未调优而持续发包到旧节点,造成“切了但没完全切”。
- 两台服务器均执行:echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore 和 echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce,确保 VIP 的 ARP 响应精准及时
- 清空 INPUT 链中对 VIP 的 DROP 规则,允许 VRRP 协议(IP 协议号 112)及 VIP 流量通过
- Nginx 重载时使用 nginx -s reload 并配置 worker_shutdown_timeout 3s,保障旧连接自然退出,不丢请求


















