在软考高级架构师的案例分析里,有四个字是绝对的“噩梦”——单点故障(SPOF, Single Point of Failure)。
题目通常是这么出的:
“某系统的反向代理服务器使用了单台 Nginx。运营期间,该服务器网卡烧了,导致全站不可用 4 小时。老板大发雷霆,要求架构师整改方案,必须保证 99.99% 的可用性。”
很多同学会说:“那简单,加一台 Nginx 不就行了?”
加是可以加,但问题来了:客户端(浏览器)只认识一个 IP 地址,现在你有两台机器,两个 IP,客户端到底连谁?如果还没连上,怎么自动切到另一台?
今天咱们就来聊聊这个让系统“永不掉线”的黄金搭档:Keepalived + VIP(虚拟 IP)。
一、 为什么“加一台”解决不了问题?
假设你原来有一台 Nginx(IP: 192.168.1.100)。 现在你买了一台新机器(IP: 192.168.1.101)。
如果 100 挂了,你得手动去改 DNS 解析,或者打电话通知所有用户:“喂,麻烦你们改一下配置,连 101 啊。” 这显然不现实。
我们需要的是一个“幽灵 IP” ——VIP(Virtual IP)。 这个 IP 不死绑在某台机器的网卡上,而是“漂浮”在空中。谁是老大(Master),这个 IP 就漂到谁头上。用户只认这个 VIP,压根不知道后面有几台机器。
二、 Keepalived 的“夺嫡之争”
Keepalived 这个软件,本质上是在玩一个“抢帽子”的游戏。
VRRP 协议(虚拟路由冗余协议) : 两台 Nginx 上都装着 Keepalived。 他们之间靠 “心跳” (Heartbeat) 沟通。主节点(Master)每秒喊一声:“我还在!我还在!” 备节点(Backup)只要听到喊声,就乖乖待着。
故障切换(Failover) : 一旦主节点网线拨了,或者 Keepalived 进程死了,不再喊了。 备节点等了 3 秒没听到声音,立刻宣布:“皇帝驾崩了,现在我登基!” 备节点迅速把 VIP 抢过来 ,绑定到自己的网卡上。
用户无感 : 用户访问的总是那个 VIP。虽然背后机器换了,除了 TCP 连接重连的一瞬间卡顿外,业务几乎不受影响。
三、 案例分析“找茬”实战
【真题模拟】某系统采用了双机热备方案。主从数据库各部署了一台。为了实现故障自动切换,架构师在应用层代码里写了心跳检测逻辑:代码每 5 秒 ping 一下主库,如果不通,就改连从库。
请分析该方案的隐患。
架构师诊断(得分点):
代码侵入性太强 :业务代码里揉进了基础架构的逻辑,不够纯粹。
切换延迟大 :应用层定时轮询有间隔,且可能有假死误判。
连接风暴 :如果是个集群应用,几十个应用实例同时发现主库挂了,同时发起切换,可能引发新的混乱。
改进建议:下沉到基础设施层。 引入 Keepalived + VIP(或者在数据库层面引入 MHA/Orchestrator)。应用层只需要配置连接那个唯一的 VIP,切换逻辑完全透明。
四、 脑裂(Split-Brain):两个皇帝怎么办?
场景: 主备之间的心跳网线断了(比如交换机故障),但两台机器本身其实都是好的。
主节点:我活着。
备节点:没听到主节点声音,它肯定死了,我上位!
结果:两个节点都抢占了 VIP。外部请求一会儿连这个,一会儿连那个,数据瞬间乱套。
架构师对策(得分点):
双心跳链路 :搞两根网线连接心跳,坏一根还有一根。
仲裁机制 :引入第三方观察者(如网关),谁能 Ping 通网关谁才是真活着。
STONITH(Shoot The Other Node In The Head) :备节点上位前,通过管理卡(IPMI)直接远程断掉主节点的电。够狠,但有效。
小结
解决单点故障,核心考点就两句话:
冗余(Redundancy) :一台不够搞两台。
自动故障转移(Failover) :Keepalived + VIP 是最经典的低成本方案。