裂脑是故障转移机制在通信失效时失去约束力的表现,关键在于“切得稳不稳”,须确保同一时刻仅一个主节点;可通过VIP冲突、VRRP报文缺失、双主日志、流量跳变等事实确认;需用单播心跳、双链路、仲裁、fence等强制决策唯一性,并构建监控-响应-验证闭环。
裂脑不是故障转移失败的结果,而是故障转移机制在通信失效时失去约束力的表现。关键不在“切换快不快”,而在“切得稳不稳”——必须让系统在心跳中断、网络分区等异常下,仍能守住“同一时刻只有一个主节点”的底线。
确认是否已发生裂脑
别靠猜测,用可验证的事实判断:
- 在所有候选节点上执行 ip addr show | grep VIP,若多个节点同时显示该 VIP 且状态为 UP,说明 VIP 已冲突;
- 在备节点运行 tcpdump -i eth0 vrrp,连续 5 秒无 VRRP 报文,基本确认心跳链路中断;
- 查 journalctl -u keepalived 或 /var/log/messages,若主、备节点日志中均出现 "Entering MASTER STATE",就是典型双升主;
- 从不同终端持续访问 VIP,用 curl -s http://VIP | grep "hostname",返回结果在多台机器间跳变,说明流量已被分流。
切断通信单点失效风险
90% 的裂脑源于心跳不可靠,必须打破对单一链路的依赖:
- 禁用组播心跳,改用 unicast_peer 配置单播直连,绕过交换机转发环节;
- 防火墙需明确放行 IP 协议号 112(不是端口),命令:iptables -A INPUT -p 112 -j ACCEPT;
- 加设第二心跳通道:独立网卡+直连线,配合 vrrp_script 检测双链路状态,任一通即维持通信判断;
- 监控 Keepalived 进程本身,避免 CPU 占满或脚本卡死导致假存活——采集 keepalived_process_status 指标,异常自动重启。
强制决策唯一性
即使心跳断了,节点也不能“自作主张”:
- 主节点 priority 必须显著高于备节点(如 150 vs 100),且所有健康检查脚本的 weight 变化后,主节点权重仍保持绝对优势;
- 启用 nopreempt,防止网络恢复后主节点强行抢回 VIP 引发震荡;
- 引入第三方仲裁(Arbiter):轻量服务独立部署,实时校验 VIP 绑定状态,发现双主立即触发强制降级;
- 配置 fence 机制(如 SSH 杀进程、存储卸载),确保旧主恢复后无法继续写入资源。
构建主动防御闭环
防御不能只靠配置,要形成可观测、可响应、可验证的闭环:
- 用 Zabbix 或 Prometheus 监控 VIP 状态、VRRP 报文收发量、进程存活、脚本执行时长;
- 在 Web 页面嵌入本机标识(如
<div id="node-id">nginx-01</div>),便于人工快速识别服务归属; - 每季度做一次故障演练:拔网线、封防火墙、杀 Keepalived 进程,验证自动恢复是否符合预期;
- 配套守护脚本:检测到双主时,自动执行 ip addr flush dev eth0 清除冲突 VIP,并发告警。