“系统怎么保证不挂”是架构设计里最难回答的问题之一,因为故障永远消灭不完。高可用的真实目标是:尽量少出故障、故障来了把影响关在小范围、并在承诺时间内恢复。本文按一条主线展开:先用几个 9 把”可用”量化,再讲故障域怎么设计,然后给出体系化的手段清单,最后落在容量规划与压测演练的验证闭环上。

可用性的度量:几个 9 的真实含义

业内用”几个 9”衡量可用性,即一段时间内服务正常的占比:

可用性 年度停机时间 典型对象
90%(1 个 9) 36.5 天 个人站点
99%(2 个 9) 3.65 天 普通企业系统
99.9%(3 个 9) 约 8.8 小时 一般在线服务
99.99%(4 个 9) 约 52.6 分钟 金融交易类系统
99.999%(5 个 9) 约 5.3 分钟 电信级设施

小数点后每多一个 9,停机预算缩小一个数量级,冗余、跨机房和演练的成本也同步跳涨。从 3 个 9 到 4 个 9,意味着全年所有故障加起来不能超过一支烟的时间,靠人工响应已经不可能,检测和切换必须自动化。

谈数字之前先约定口径,否则各说各话:按自然月还是自然年统计?计划内停机维护算不算?全站统一一个指标,还是核心链路与非核心链路分开承诺?另一种口径按请求算——失败请求数占总请求数的比例,它对”部分不可用”(比如只有 5% 的用户受影响)更敏感,互联网公司更常用。对外承诺时这些口径会写进 SLA(Service Level Agreement,服务等级协议):云厂商承诺 99.95%,意味着每月停机预算约 22 分钟,超了要赔付。内部目标(SLO)通常定得比 SLA 更严一档,为意外留出缓冲带。

系统为什么会不可用

归因无非内外两类。内部:代码缺陷(内存泄漏、死锁)、架构缺陷(单点、强耦合)、资源耗尽(CPU、磁盘、连接池)、配置错误。外部:硬件故障、流量突增(秒杀开场)、网络攻击、依赖服务故障、机房级灾难。这份清单的价值在于提醒:提高可用性不是买更多机器,而是针对每一类失效模式准备对应的手段。下面按”故障域设计 → 手段清单 → 验证闭环”展开。

故障域设计:把爆炸半径关小

冗余是物理基础:任何关键资源至少两份,坏一份有替补。冗余可以发生在每个层级——硬件(双电源、RAID)、服务(多实例集群)、数据(主从复制、多副本)、网络(多运营商接入)、地域(同城双机房、异地多活)。但要注意:冗余不等于高可用。多副本如果共用同一套配置、同一条发布流水线、同一个机房供电,一次错误发布或一次断电照样全灭。

隔离决定故障的扩散范围。线程池隔离给每个下游依赖单独的线程池或信号量,一个依赖变慢只占用自己的配额,不会拖垮整个服务;部署层面,核心服务与非核心服务分开,抢资源时先牺牲非核心;数据层面,分库分表让单库故障只影响一部分用户。

单元化是隔离思想的极致形态:按用户或地域把流量切成若干自治单元,每个单元拥有完整的应用、缓存、数据库,单元之间故障互不传染,单个单元坏了只损失 1/N 的用户。代价是路由规则、跨单元数据一致性和运维复杂度大幅上升,只有对可用性要求极高的核心业务才值得做。

体系化手段清单

高可用手段可以按故障生命周期分三段组织:预防(少出事)、容错(出事扛住)、恢复(快速回来)。

预防阶段:

  • 代码质量与评审:线上故障最大的单一来源仍是代码与变更。Code Review、静态扫描(SonarQube)、规范插件是最便宜的可用性投资。
  • 变更管控:灰度发布把集群分批放量,每批观察稳定再推下一批,发现问题只回滚已放量的部分;配置变更同样走灰度。
  • 容量冗余:核心链路留出余量,不为省机器把日常水位跑到 90%。

容错阶段(流量沿调用链往下走时逐层设防):

  • 限流:入口第一道防线,按 QPS 或并发数阈值把超出能力的流量挡在外面,常见算法有滑动窗口、漏桶、令牌桶。
  • 超时与重试:所有远程调用必须设超时;重试限制次数并配指数退避加抖动,写操作先解决幂等。
  • 熔断:下游持续异常时熔断器打开,请求快速失败不再调用,给下游恢复时间;冷却后进入半开状态放少量流量试探,成功则闭合。
  • 降级:系统吃紧时关掉非核心功能(推荐、评论),或返回缓存与默认数据,保核心链路。
  • 异步削峰:用消息队列把瞬时洪峰摊平,代价是业务流程要改成异步通知模式。
  • 缓存:热点数据挡在数据库前面,同时防住穿透(布隆过滤器、空值缓存)、击穿(互斥重建)、雪崩(过期时间加随机偏移)。

恢复阶段:

  • 监控告警:盯黄金指标(流量、错误、延迟、饱和度),告警要比用户投诉先到。
  • 故障转移:主备或集群配合健康检查自动摘除故障节点;数据库等有状态组件切换时要防脑裂。
  • 备份与回滚:数据库定期备份,且只有恢复演练成功过的备份才可信;代码和配置可随时回滚。
  • 混沌工程:主动注入故障(随机关机、注入延迟、断网)验证容错设计真的生效,而不是停留在文档上。

容量规划与压测的闭环

高可用不是设计出来的,是测出来的。闭环长这样:

  1. 估算:用历史流量和增长预期估出峰值 QPS,结合 Little 定律换算目标并发,再加 1.5~2 倍安全冗余,得到容量假设。
  2. 压测验证:单接口压测摸清各节点极限,全链路压测验证真实业务模型下的瓶颈——瓶颈经常不在你以为的地方:应用 CPU 还很闲,数据库连接池先打满了。
  3. 演练验证容错:压测证明”扛得住”,故障演练证明”坏了能回来”。杀节点、断网络、制造慢下游,确认限流、熔断、降级、切换按设计动作。
  4. 复盘修正:把演练和真实事故暴露的偏差(瓶颈位置猜错、告警晚于用户反馈、恢复依赖某个人手动操作)变成下一轮改进项。

这个闭环每个大促前都要完整跑一遍,系统结构每变一次也要重跑——容量结论是会过期的。

小结

  • 高可用的目标是限制故障影响并在承诺时间内恢复,而不是消灭故障。
  • 几个 9 是承诺也是成本,先定口径再谈数字;核心与非核心链路可以分级。
  • 故障域设计靠冗余、隔离、单元化,把单次故障的爆炸半径关到最小。
  • 手段清单按预防、容错、恢复组织,沿调用链逐层设防。
  • 容量规划—压测—演练—复盘的闭环,是高可用唯一可信的验证方式。