如何实现系统的高可用性
来源:如何实现系统的高可用性
在架构师或高级开发工程师的面试中,“请讲讲你理解的高可用系统是如何设计的?”是一个极高频的“劝退题”。
很多求职者简历上写着“负责千万级高可用架构”、“99.99% SLA”,但一被问到细节,往往只能憋出一句:“呃……就是多加几台服务器?”
如果这么回答,基本上就离“回家等通知”不远了。今天我们就结合实战场景,像剥洋葱一样,层层递进地解析这个面试题,带你从“加服务器”一路进阶到“异地多活”。
核心思维:高可用的本质是“冗余”
首先,开篇点题。高可用(High Availability, HA)的核心确实离不开冗余(Redundancy)。
通俗点说,就是“鸡蛋不要放在一个篮子里”。并不是要追求服务器永远不挂(那是不可能的),而是当某台机器挂掉时,有备份立马顶上来,让用户感觉不到故障的存在。
初级回答:“做集群,部署两台 Tomcat。” 面试官追问:“那用户请求发给谁?你前面总得有个入口吧?比如 Nginx。”

这就引出了第一关的挑战。
第 1 关:解决“入口”的单点故障—— 网关层高可用
如果你有两台 Tomcat,前面挡了一台 Nginx 做负载均衡。Tomcat 是冗余了,但 Nginx 成了新的单点(SPOF)。一旦这台 Nginx 宕机,后端无论有多少台健康的服务器,整个系统都会对外表现为“全瘫”。
解决方案:Keepalived + VIP(虚拟 IP)

- 架构设计:部署两台 Nginx,分为主节点(Master)和备节点(Backup)。
- 核心机制:
- 心跳检测:Keepalived 在主备之间持续发送心跳包。
- IP 漂移:正常情况下,VIP 绑定在 Master 上。一旦 Master 宕机(心跳停止),VIP 会在毫秒级时间内“漂移”到 Backup 节点上,流量随之自动切换。
- 关键词:故障转移(Failover)。不仅要有备份,还要有自动切换的能力。
第 2 关:解决“心脏”的停跳风险—— 数据层高可用
应用层和网关层搞定了,但系统最脆弱的往往是数据库。数据库如果是单机,一旦宕机,数据读写全停,业务直接归零。
通常我们会做“一主多从”来实现读写分离和备份。但这里有一个致命问题:如果半夜 3 点主库挂了怎么办? 指望运维人员半夜爬起来手动修改配置、提升从库吗?这几分钟甚至几十分钟的业务中断是不可接受的。
解决方案:哨兵机制(Sentinel)或 MHA

- 架构设计:引入“哨兵”组件(监控集群)。
- 核心机制:
- 自动监控:7x24 小时监控主库状态。
- 自动选举:主库故障时,哨兵通过投票机制,自动在从库中选出一个新的主库。
- 自动切换:自动完成主从切换配置。
- 关键词:自动故障转移(Auto-Failover)。将故障恢复时间从分钟级压缩到秒级。
第 3 关:抵御流量洪峰的冲击—— 服务雪崩与自我保护
前两关解决的是“自身生病”的问题,这一关要解决“外界压力”的问题。比如秒杀活动,瞬间流量暴涨 10 倍,CPU 飙升 100%,导致所有请求超时,系统被压垮。这被称为服务雪崩。
解决方案:限流(Rate Limiting)

核心思想:“扛不住,就别硬扛”。牺牲一部分用户的体验(直接拒绝多余请求),来保住核心系统的存活。
常见算法:
令牌桶算法:允许一定的突发流量。
漏桶算法:强制平滑流量速率。
关键词:丢车保帅。
第 4 关:防止“猪队友”拖死自己—— 级联故障与隔离
在微服务架构中,服务 A 调用服务 B。如果服务 B 响应极慢或 hang 住,服务 A 的线程池会被大量积压的请求占满,导致服务 A 也无法响应其他正常请求。这就是级联故障。
解决方案:熔断(Circuit Breaking)

- 核心机制:类似电路中的“保险丝”。
- 拉闸(Open):当检测到下游服务(服务 B)的错误率或超时率达到阈值,熔断器直接打开。
- 快速失败(Fast-Fail):后续对服务 B 的调用不再真正发出,而是直接返回错误,释放线程资源。
- 半开(Half-Open):过一段时间尝试放行少量请求,如果成功则恢复。
- 关键词:故障隔离。
第 5 关:终极挑战——天灾人祸—— 容灾架构
如果面试官祭出大招:“如果光纤被挖断了?机房起火了?地震了怎么办?” 如果你所有的服务器、备份都在同一个机房,那这就是物理层面的“一锅端”,所有软件层面的高可用都将失效。
解决方案:异地多活(Multi-Site High Availability)

架构设计:
同城双活:同城两个不同机房。
异地多活:跨城市部署(如北京 + 上海)。
核心难点:跨地域的数据实时同步与一致性保障(这是架构设计的深水区)。
关键词:容灾(Disaster Recovery)。
总结:如何回答“怎么设计高可用系统”?
真正的满分回答,不是堆砌技术名词,而是展示你的防御思维。你可以这样总结:
“高可用不仅仅是多部署几台机器,而是对故障的敬畏。我通常从以下几个层面来构建防御体系:
- 架构冗余:利用 Keepalived 和 VIP 解决网关单点,利用哨兵机制解决数据库单点。
- 流量治理:利用限流算法抵御流量洪峰,防止机器被打挂。
- 依赖治理:利用熔断降级机制,防止被下游的不稳定服务拖垮。
- 物理容灾:在资源允许的情况下,实施同城双活甚至异地多活,抵御数据中心级别的灾难。
我们的目标不是设计一个‘永不宕机’的系统,而是设计一个能快速从故障中恢复的系统。”