"自动切换"听起来像是一个开关,打开之后服务器坏了系统自己就顶上去了。但真正做过高可用的人都知道,自动切换是一整套机制的协同结果:谁来发现问题、多久算超时、切换什么、谁来执行、切换后再怎么恢复、如果判断错误怎么办。任何一个环节没设计好,轻则切换失灵,重则出现双主、数据错乱这种比单纯宕机更麻烦的故障。
这篇文章系统讲清楚服务器集群故障自动切换的设计方法。从故障检测的几种手段(心跳、TCP 探测、HTTP 健康检查)讲起,说明 VIP 切换、DNS 切流、负载均衡摘除节点各自的适用场景,比较 Keepalived、Pacemaker 和云负载均衡的定位差异,重点分析脑裂的成因和仲裁防护,最后给出可执行的切换演练和验证方法。涉及删除、改防火墙的操作都会标注风险与回滚方式,Linux 部分区分 RHEL/CentOS/Rocky 与 Debian/Ubuntu 两套发行版。
自动切换的四个关键环节
把自动切换拆开,无非四件事:检测、决策、执行、恢复。
检测是判断节点是否健康。决策是根据检测结果决定要不要切、切给谁。执行是真正把流量或资源转移过去。恢复是故障节点回来后如何重新纳入集群,避免它带着旧状态乱入。
这四步里最容易出问题的是"检测"和"决策"。检测太敏感,网络抖一下就误切,造成不必要的抖动;检测太迟钝,真故障了迟迟不切,可用性达不到要求。决策则涉及超时阈值、失败次数、是否有多数节点确认,直接决定了会不会脑裂。
还有一条容易被忽略的原则:自动切换必须能"演练"。没有演练过的故障切换,等于没有。因为真正的切换往往暴露出配置不一致、脚本报错、依赖缺失这些平时看不到的问题。
故障检测:心跳、TCP 探测与 HTTP 健康检查
检测手段大致分三个层次,越往下越接近业务真实状态。
心跳是最基础的层次。节点之间定期发送心跳包,超时未收到就认为对端异常。心跳可以是网络层(如 VRRP 通告)、传输层(TCP 长连接)、也可以是应用层(自定义协议)。心跳简单高效,但只能说明"网络通不通"或"进程在不在",不能说明业务是否可用。比如 Nginx 进程还在但后端全挂了,心跳仍然是通的。
TCP 探测进了一步,针对具体端口发起连接,能连上就认为服务在监听。它比心跳更贴近服务,但仍然不能保证业务逻辑正常。比如应用连不上数据库,端口照样在监听。
HTTP 健康检查最贴近业务。通过访问一个专门的健康检查接口,返回 200 才认为健康,接口内部可以去探测数据库、缓存等依赖。这样即使依赖出问题,也能被感知。代价是检测成本更高,需要应用配合实现健康接口。
实际生产里通常是组合使用:Keepalived 用心跳加脚本,LVS 用 TCP 探测,Nginx、HAProxy、云负载均衡用 HTTP 健康检查。层次越深,越能反映真实可用性,但也越容易被误报影响。下面是一个应用健康接口返回 JSON 的示意,健康检查配置期望 200 状态码即可:
{
"status": "UP",
"db": "UP",
"redis": "UP"
}
VIP 切换、DNS 切流与负载均衡摘除
检测到故障后,怎么把流量转走,有三类主要方式,各有适用场景。
VIP 切换是最常见的入口层方案。用 Keepalived 或类似工具维护一个虚拟 IP,主节点故障时把 VIP 漂移到备节点。它对客户端透明,切换在秒级完成,适合同一网段内的高可用。局限是要求节点同网段、VIP 数量有限、跨机房不适用。
DNS 切流通过修改域名解析把流量指向另一个地址。它适合跨地域、跨机房、跨服务商的场景,但受 DNS 缓存 TTL 影响,切换生效慢(分钟级甚至更久),而且客户端和递归服务器可能缓存旧记录。所以 DNS 切流通常用于异地容灾的兜底,不作为主流的秒级切换手段。降低 TTL 可以缩短生效时间,但会增加 DNS 查询压力。
负载均衡摘除节点是在负载均衡层把故障后端从池子里拿掉。Nginx、HAProxy、LVS 都能通过健康检查自动摘除失败节点,恢复后自动加回。这是应用层高可用最常用的方式,因为它不改变入口地址,只调整后端的成员列表。它的前提是入口层本身要有多副本,否则入口一挂全完。
现实中往往三者配合:入口层用 VIP 保证高可用,中间用负载均衡做健康检查摘除后端,跨地域用 DNS 或全局负载均衡做就近与容灾。
Keepalived、Pacemaker 与云负载均衡的定位
自动切换工具很多,定位差异很大,选错了要么能力不足,要么过度复杂。
Keepalived 轻量、专注,适合双机主备和 LVS 的高可用。它用 VRRP 选主,管理 VIP 漂移,配合脚本做健康检查。优点是配置简单、资源占用低;缺点是资源管理能力弱,不适合管理复杂的有状态集群(比如数据库主从的角色切换),也不擅长多节点仲裁。
Pacemaker 加 Corosync 是重量级的集群资源管理器,能管理 VIP、文件系统、数据库、自定义资源,支持资源依赖、约束、多节点仲裁和 fencing。它适合有状态服务的高可用,比如数据库、共享存储挂载。代价是配置复杂、学习曲线陡,运维门槛高。
云负载均衡是主流云厂商提供的托管负载均衡服务,自带健康检查和后端摘除,跨可用区部署,无需自己维护入口节点。它的优点是省心、天然高可用;缺点是依赖云平台、成本随流量上升、行为受平台限制。对中小企业和个人站长,能用托管的就尽量用托管,把精力放在业务上。
| 方案 | 定位 | 优势 | 局限 | 适用场景 |
|---|---|---|---|---|
| Keepalived | 轻量双机主备 | 简单、省资源、秒级漂移 | 有状态资源管理弱 | 入口层、LVS 高可用 |
| Pacemaker | 重量级资源管理 | 支持复杂资源与仲裁 | 配置复杂、门槛高 | 数据库、共享存储 |
| 云负载均衡 | 托管服务 | 免运维、跨可用区 | 依赖云平台、成本随量 | 云上业务、中小规模 |
配置 Keepalived 做 VIP 漂移的完整方法可以参考本系列前两篇,这里只强调一点:无论用哪种工具,健康检查脚本都要覆盖真正影响业务的服务,不能只检查进程是否存活。下面是一个加入 HTTP 探测的健康检查脚本示例:
#!/usr/bin/env bash
# /etc/keepalived/chk_web.sh:HTTP 健康检查,非 200 视为异常
code=$(curl -s -o /dev/null -w '%{http_code}' --max-time 2 http://127.0.0.1/healthz)
[ "$code" = "200" ] && exit 0 || exit 1
脚本要短、要幂等、要设超时,避免因为脚本自身卡住而拖慢状态机。
脑裂防护与仲裁机制
脑裂是自动切换里最危险的问题:两个节点都认为自己是主,同时对外服务,造成冲突。以 Keepalived 为例,主备之间通信中断(网络分区、VRRP 被拦),双方都收不到对方通告,可能各自成为 MASTER,同时持有 VIP。
脑裂的成因主要是通信链路不可靠、配置错误(如 virtual_router_id 冲突)、以及没有第三方仲裁。防护手段有几层。
第一层是通信冗余。让主备之间有多条通信路径,避免单条链路故障被误判为节点故障。云环境优先用单播模式,明确指定对端,不依赖组播。
第二层是第三方仲裁(quorum)。引入一个第三方(仲裁节点、见证节点或多数派)来判断谁该当主。只有获得多数同意的节点才能成为主,单边网络分割时拿不到多数,就不会双主。Pacemaker 的仲裁机制、Redis 哨兵的 quorum、数据库的多数派选举都是这个思路。
第三层是 fencing(隔离)。当仲裁判定某节点该下线时,通过断电、封网卡、关机等方式强制把它隔离,确保它不会继续写数据。这是有状态集群(尤其数据库和共享存储)必须考虑的一环,否则隔离不彻底会导致数据被两边同时修改。
第四层是应用层的租约和心跳。用带超时的分布式锁或租约,谁持有的租约有效谁才是主,过期自动释放。
可以这样理解:心跳负责发现问题,仲裁负责避免误判,fencing 负责确保被判定下线的节点真的停止工作。三者缺一不可。
切换演练与验证方法
再好的设计,不演练都是纸上谈兵。演练要有计划、可回滚、可观测。
准备阶段先确认演练窗口、影响范围、回滚方案,通知相关方,并确保有控制台或带外管理手段。开始前记录当前状态:哪台是主、VIP 在哪、后端有哪些。
演练时逐个制造故障。先测应用层故障:停掉主节点的业务进程,观察是否触发切换。
# 风险提示:会让本节点业务短暂中断,请在演练窗口执行
sudo systemctl stop nginx
观察备节点是否接管(VIP 漂移或负载均衡摘除),客户端访问是否恢复。再测节点级故障:停掉主节点的 Keepalived,或在云控制台对实例做重启。还可以模拟网络故障,用防火墙临时阻断主备之间的心跳端口,观察是否出现脑裂——这是最能暴露问题的一项测试。
# 风险提示:阻断心跳会导致集群判定异常,务必在隔离的演练环境做
# RHEL / CentOS / Rocky 系:临时拒绝 VRRP
sudo firewall-cmd --add-rich-rule='rule protocol value="vrrp" drop' --timeout=30
验证要点包括:切换耗时(目标通常秒级)、客户端是否出现明显报错、数据是否一致、监控告警是否触发、切换后自动恢复是否正常。每次演练都要记录结果和问题,形成固定的 checklist。
演练结束务必恢复所有临时改动,并确认监控、日志、告警都回到正常。风险提示: 演练中修改的防火墙规则、内核参数、服务状态都要有明确的回滚清单,避免遗留隐患。
常见问题
自动切换和手动切换怎么选?
核心入口和数据层建议自动切换,减少故障恢复时间;涉及数据一致性、难以自动判断的场景(如主从切换可能丢数据)可以先告警、人工确认后切换。关键是把"什么时候自动、什么时候人工"写进预案。
切换时间能做到多快?
VIP 漂移通常 1 到 5 秒,负载均衡摘除节点取决于健康检查间隔和失败阈值,通常也是秒级到十几秒。DNS 切流受 TTL 影响,可能分钟级。目标要按业务能接受的中断时间来定,不必一味追求极快。
为什么健康检查会把正常节点判成故障?
常见原因是检查间隔太短、超时太紧、健康接口自身依赖不稳。不要用"能 ping 通"作为唯一标准,健康接口应只检查最关键依赖。还要注意健康检查本身不能被限流或需要认证。
云服务器能用 Keepalived 吗?
可以,但很多云环境屏蔽组播,需要改用单播模式,并确认云平台允许自定义 VIP 和 ARP。部分云平台对 VIP 有额外限制,动手前先查阅平台网络文档。
有状态服务能自动切换吗?
能,但复杂。数据库、共享存储这类有状态服务涉及数据一致性,需要配合复制、仲裁和 fencing,通常用 Pacemaker 或数据库自带的高可用方案,不能简单套用入口层的方案。
总结
- 自动切换由检测、决策、执行、恢复四个环节构成,检测要贴近业务,决策要防误判,恢复要防脏状态。
- 检测手段分心跳、TCP 探测、HTTP 健康检查三层,层次越深越贴近真实可用性,生产建议组合使用。
- 流量转移有 VIP 切换、DNS 切流、负载均衡摘除三类方式,分别适合同网段、跨地域和后端成员调整。
- Keepalived 轻量适合入口层,Pacemaker 适合有状态资源,云负载均衡省心但依赖平台,按场景选型。
- 脑裂靠通信冗余、第三方仲裁和 fencing 三层防护,自动切换必须通过实际演练验证,否则等于没有。
企业QQ咨询




