什么是高可用?分布式系统为什么要做高可用设计?
简化版
高可用是指系统在机器故障、网络抖动、依赖异常、流量突增等情况下,仍能尽量持续提供服务。分布式系统做高可用的核心不是让故障消失,而是通过冗余、隔离、故障检测、自动切换、降级和恢复,把故障影响控制在可接受范围内。
详细版
高可用通常围绕几个目标展开:
- 减少单点故障,关键组件要有冗余;
- 快速发现故障,通过心跳、健康检查、指标和日志判断异常;
- 自动或半自动切换,把流量从故障节点切到健康节点;
- 控制故障范围,用隔离、限流、熔断、降级避免故障扩散;
- 保证数据可恢复,通过复制、备份、容灾和对账降低数据损失;
- 建立可演练机制,通过压测、故障演练、混沌工程验证预案。
面试回答时要强调:高可用不是单个技术点,而是一套工程体系。负载均衡、主从复制、多副本、注册中心、超时重试、熔断降级、备份恢复、同城双活和异地容灾,都是为了让系统在局部失败时仍能对外工作。
完整版教学
一、先接受一个事实:故障一定会发生
很多初学者理解高可用时,会下意识追求“系统不要出故障”。但在分布式系统里,这个目标不现实。机器会宕机,磁盘会坏,网络会丢包,机房会断电,代码会有 bug,下游服务会超时,流量也可能突然放大几十倍。
高可用的成熟思路不是假设故障不会发生,而是假设故障一定会发生,然后提前设计系统在故障下的行为。比如某个应用实例挂了,负载均衡能不能摘掉它;某个数据库主库挂了,能不能切到从库;某个下游接口超时,本服务能不能快速失败或降级;某个机房不可用,核心链路能不能切到另一个机房。
所以高可用是一种“带故障运行”的能力。系统不是玻璃制品,碰一下就碎;更像分段船舱,一个舱进水时不会立刻沉没。
二、高可用最常用的第一招是冗余
单点故障是高可用的大敌。只有一个应用实例、一个数据库、一个缓存节点、一个网关、一个机房,都意味着这个点挂掉后系统无法继续提供服务。冗余就是为关键组件准备多个可替代节点。
应用服务通常通过多实例部署实现冗余,前面挂负载均衡。缓存可以做主从、哨兵或集群。数据库可以做主从复制、半同步复制、MGR、分片多副本。消息队列可以做多 Broker、多副本、ISR 或主从。机房层面可以做多可用区、多机房容灾。
但冗余不只是“多部署几台”。如果所有实例都依赖同一个配置中心、同一个数据库、同一个机柜电源,那么单点仍然存在。高可用设计要画出完整依赖链路,找出任何一个“挂了大家都挂”的点。
三、故障检测决定切换速度
有冗余还不够,系统必须知道哪个节点坏了。常见检测方式包括心跳、健康检查、指标探针、业务探活、日志告警等。
最简单的健康检查只判断进程是否存活,比如 HTTP /health 返回 200。但进程活着不代表能正常服务:线程池可能满了,数据库连接池可能耗尽,依赖接口可能全部超时。因此更严谨的健康检查会区分存活检查和就绪检查。存活检查判断进程是否应该重启,就绪检查判断实例是否应该接流量。
故障检测有一个经典取舍:检测太慢,故障恢复时间长;检测太激进,网络抖动时可能误判,把健康节点踢掉,甚至造成频繁切换。高可用不是越快切越好,而是要在误判和恢复速度之间取得平衡。
四、自动切换要有防抖和回滚
故障切换看起来很美:主节点挂了,系统自动切到备节点。但切换本身也有风险。比如主库只是短暂网络抖动,如果从库误升主,旧主恢复后可能出现双主写入;服务实例刚因为 GC 暂停几秒,如果立刻被摘除再加入,可能造成流量抖动。
因此自动切换通常要配合防抖策略:连续多次探测失败才判定故障,切换后设置冷却时间,恢复节点先预热再接流量。数据库、注册中心、消息队列这类有状态组件还要特别防止脑裂,通常需要多数派、租约、仲裁节点或人工确认。
切换还必须有回滚预案。高可用系统真正怕的不是故障,而是故障处理动作扩大事故。任何自动化都要可观测、可暂停、可回退。
五、高可用还包括“降级运行”
不是所有故障都必须完全恢复后才能服务。有些功能可以临时降级。比如商品详情页推荐模块失败,主商品信息仍然可以展示;积分服务超时,订单可以先创建,积分稍后补发;报表导出慢,可以进入异步队列。
降级的关键是划分核心链路和非核心链路。核心链路要尽量保住,非核心链路可以延迟、缓存、默认值、隐藏入口或提示稍后再试。这样系统在压力下不会因为一个边缘功能拖垮主流程。
六、高可用设计要覆盖从入口到数据的整条链路
只给应用服务做多实例,并不能说明系统高可用。用户请求从 DNS、CDN、负载均衡、网关、应用服务、缓存、数据库、消息队列、第三方依赖一路走下去,任何关键点不可用都可能让用户感知失败。因此做高可用评审时,要画完整链路图,而不是只看某一层。
入口层要考虑 DNS 解析、证书、负载均衡自身冗余和限流能力。应用层要考虑无状态、多实例、线程池隔离、超时重试、熔断降级。缓存层要考虑主从、集群、热点 Key、穿透击穿雪崩。数据库层要考虑主从复制、故障切换、备份恢复、主从延迟和容量。消息层要考虑 Broker 副本、消息堆积、重复消费和死信处理。外部依赖要考虑降级、备用供应商和人工兜底流程。
高可用不是堆组件,而是确保每一层都有故障行为:它坏了怎么发现,谁来接替,数据差多少,用户看到什么,多久恢复,恢复后如何校验。
七、高可用建设要分等级,不同业务不能一刀切
支付、下单、登录、订单查询、推荐、报表的高可用等级不应该一样。核心交易链路可能要求分钟级恢复甚至秒级切换,数据 RPO 接近 0;推荐和评论可以降级;运营报表可以延迟恢复。没有业务分级,就会出现两种问题:要么所有系统都按最高标准建设,成本爆炸;要么核心链路也只做普通保障,风险过高。
工程上可以按业务重要性定义等级:核心链路要求多 AZ、多副本、自动切换、强监控和值班;重要链路要求主备和快速恢复;普通链路可以依赖备份和人工恢复。每个等级明确 SLO、RTO、RPO、演练频率和报警级别。
面试时如果只说“加机器、做集群”,答案会很浅。更好的回答是把高可用看成体系:目标分级、架构冗余、故障检测、隔离降级、数据恢复、演练复盘。这样才能说明你理解的是生产系统稳定性,而不是单个中间件功能。
八、常见误区与追问
这道题要紧扣「高可用」本身回答,不能把它混成泛泛的高可用套话。面试官通常不是只听定义,而是看你能不能把适用场景、关键流程、失败边界和工程取舍串起来,尤其要说明故障域、冗余、健康检查、切换流程、RPO/RTO 和演练结果。
| 回答层次 | 要讲清的内容 | 容易漏掉的边界 |
|---|---|---|
| 核心结论 | 高可用是系统面对故障仍尽量持续提供服务,核心是冗余、隔离、检测、切换、降级和恢复 | 不要停在名词解释 |
| 流程机制 | 识别核心链路 -> 消除单点 -> 部署冗余副本 -> 监控健康状态 -> 自动切换和降级 -> 复盘并演练 | 要说清触发点、状态变化、确认点和失败兜底 |
| 工程取舍 | 99.9% 可用性每月约 43.2 分钟不可用,想提升到 99.99% 就要把月故障压到约 4.32 分钟 | 高可用不是永不故障,而是用冗余、隔离、自动切换和演练降低故障影响 |
高可用 面试拆解:
1. 识别核心链路
2. 消除单点
3. 部署冗余副本
4. 监控健康状态
5. 自动切换和降级
6. 复盘并演练
记忆钩子:先给结论,再拆流程,再讲数字例子和失败边界;回答「高可用」时要围绕题目问法收束,不要把相邻概念堆成一段没有重点的名词清单。
- 误区:高可用就是机器多。 还要有自动发现、切换、限流、降级和恢复流程。
- 误区:高可用等于不出故障。 故障一定会发生,高可用关注影响范围和恢复速度。
- 误区:所有系统都要五个 9。 可用性目标要和业务损失及成本匹配。
- 追问:高可用核心手段? 冗余、隔离、限流降级、健康检查、故障转移和演练。
- 追问:如何衡量高可用? SLA、错误率、超时率、RTO、RPO 和故障影响面。
- 追问:如何从架构上提升? 拆故障域、消除单点、异地容灾、自动化发布和回滚。
九、加强记忆
高可用的主线可以记成“冗余承接、检测发现、切换恢复、隔离止血、降级保主链路、备份兜底”。它不是某个中间件自带的神奇能力,而是从架构、代码、数据、运维和演练一起构成的抗故障体系。