keepalived vip漂移核心是“稳”而非“快”,需分层设置超时:vrrp心跳超时(advert_int×fall)防网络抖动,应用层健康检查超时(如curl -m3)确保服务真实可用,且脚本耗时须小于vrrp超时阈值,避免误切。

设置合理的超时时间触发 VIP 漂移,核心不是“快”,而是“稳”——要避开瞬时抖动误判,又不能拖太久导致业务中断。关键在于把检测逻辑分层:先确认服务真不可用,再启动漂移,而不是一丢包就切。
区分两类超时:心跳超时 vs 服务健康超时
Keepalived 默认的心跳检测(VRRP 报文)只反映主机网络连通性,不等于服务可用。比如 Nginx 进程崩溃但系统还活着,VRRP 仍能通信,VIP 就不会动。所以必须叠加应用层健康检查:
-
advert_int + fall:控制 VRRP 心跳频率和连续丢失次数。例如
advert_int 1; fall 3表示 3 秒没收到主节点报文才触发选举,适合局域网;跨机房建议调大到fall 5~6防抖动 -
check script 超时:脚本内用
curl -m 3或mysql -h127.0.0.1 -P3306 -e "SELECT 1" -uuser -ppass等命令,显式加-m(秒级超时)。脚本执行总耗时应小于advert_int × fall,否则可能被判定为“检查失败”而非“服务异常”
避免常见误配组合
很多故障源于参数间隐含依赖,单独看都合理,合起来就出问题:
- 心跳间隔设太短(
advert_int 0.5),但脚本里 MySQL 连接+查询平均要 800ms —— 多次检查排队超时,BACKUP 节点频繁收不到响应,误升为 MASTER - 脚本返回码逻辑错误:比如 MySQL 检查脚本在连接拒绝时 exit 0(成功),而实际该返回非 0 才代表服务异常,导致 Keepalived 认为“一切正常”,死活不漂移
- 未设置
rise参数:服务刚恢复时,连续通过 2 次检查才认定“已就绪”,避免刚加载完就切流量过去导致 502
生产环境推荐配置思路
不靠拍脑袋,而是基于真实观测定值:
- 在从库或代理节点上,用
time mysql -h$VIP -P3306 -e "SELECT 1"实测 VIP 访问延迟,取 P95 值 × 2 作为脚本超时基准(例如实测最大 1.2s,则设-m 3) - VRRP 层超时 = 应用层检查周期 × 容忍失败次数。若脚本每 5 秒跑一次、允许失败 2 次,那
advert_int 5; fall 2就是底线,再小就失去容错意义 - 对数据库类服务,建议额外加一层保护:在 check script 中判断
show global status like 'Threads_connected'是否低于阈值,防止连接池打满后“能连但不响应”
验证是否生效的简单方法
别等真出事才测试:
- 手动停掉主节点上的目标服务(如
systemctl stop mysqld),观察 BACKUP 节点日志中是否出现Entering MASTER STATE,同时ip addr show确认 VIP 已绑定 - 模拟网络抖动:
tc qdisc add dev eth0 root netem loss 50%,持续 10 秒后清除,确认 VIP 不发生误漂移 - 用
tcpdump -i eth0 host 224.0.0.18抓 VRRP 组播报文,核对发送间隔和优先级字段是否符合配置











