高可用系统如何定义可用性

一、可用性怎么定义:两种口径

「可用性」不是一个自然存在的数字,而是你自己定义出来的。定义方式不同,同一个系统能算出完全不同的可用率。这是所有讨论的前提。

1.1 时间维度(传统运维口径)

Availability = 正常运行时间 正常运行时间 + 不可用时间 \text{Availability} = \frac{\text{正常运行时间}}{\text{正常运行时间} + \text{不可用时间}} Availability=正常运行时间+不可用时间正常运行时间

问题在于「不可用」的判定极其模糊:部分接口 500 算不算?响应从 50ms 涨到 5s 算不算?10% 的用户受影响算不算?这个口径在分布式系统里几乎无法客观执行,因为现代故障大多是「部分降级」而非「整体宕机」。

1.2 请求维度(SRE 口径,推荐)

Availability = 成功请求数 总请求数 \text{Availability} = \frac{\text{成功请求数}}{\text{总请求数}} Availability=总请求数成功请求数

这个口径可客观测量、可自动计算、天然反映用户实际感知。Google SRE 和主流云厂商都用它。

但**「成功」的定义必须写清楚**,否则数字没有意义。一个完整的定义应该长这样:

在 5 分钟滚动窗口内,/api/order/create 的 HTTP 状态码非 5xx P99 延迟 < 500ms 的请求占比。

注意两点:

  • 必须包含延迟条件 。只统计错误率的话,一个「所有请求都返回 200 但耗时 30 秒」的系统可用性是 100%------而用户早就跑了。慢等于不可用
  • 4xx 通常不计入(客户端自己参数传错,不是你的故障),但要小心 401/429 这类可能由服务端问题引发的状态码。

二、MTBF 与 MTTR:可用性的两个杠杆

从可靠性工程的角度,可用性还有一个等价表达:

Availability = MTBF MTBF + MTTR \text{Availability} = \frac{\text{MTBF}}{\text{MTBF} + \text{MTTR}} Availability=MTBF+MTTRMTBF

这个公式揭示了一个关键判断:追求「不出故障」是徒劳的,工程重心应该放在「快速恢复」上。

原因是 MTBF 的提升有物理上限(硬件会坏、网络会抖、依赖方会挂、人会误操作),而 MTTR 的压缩空间巨大。把 MTTR 从 30 分钟压到 3 分钟,可用性直接提升一个数量级,成本远低于把 MTBF 翻十倍。

MTTR 还能继续拆解,这是排查优化点的正确方式:

MTTR = 发现 ⏟ MTTD + 定位 + 修复 + 验证 \text{MTTR} = \underbrace{\text{发现}}_{\text{MTTD}} + \text{定位} + \text{修复} + \text{验证} MTTR=MTTD 发现+定位+修复+验证

阶段 优化手段
发现(MTTD) 监控告警覆盖率。很多故障是用户投诉才发现的,这个阶段往往占 MTTR 的大头
定位 链路追踪、结构化日志、指标下钻
修复 一键回滚、开关降级、快速扩容------预案要提前演练,不是故障时现写脚本
验证 自动化冒烟验证

你做 Monitor 项目,本质上就是在攻 MTTD 这一段------它是整条链路上性价比最高的投入点。


三、几个 9 分别意味着什么

以下数字为实际计算结果(年按 365 天,月按 30 天):

可用性 年停机 月停机 周停机 日停机 典型定位
99%(2 个 9) 3.65 天 7.2 小时 1.68 小时 14.4 分钟 内部工具、离线任务
99.9%(3 个 9) 8.76 小时 43.2 分钟 10.08 分钟 1.44 分钟 一般业务系统,多数 SLA 的起点
99.95% 4.38 小时 21.6 分钟 5.04 分钟 43.2 秒 云厂商常见承诺档
99.99%(4 个 9) 52.56 分钟 4.32 分钟 1.01 分钟 8.64 秒 核心交易、支付链路
99.999%(5 个 9) 5.26 分钟 25.92 秒 6.05 秒 0.86 秒 电信级、金融清算
99.9999%(6 个 9) 31.54 秒 2.59 秒 0.6 秒 0.09 秒 极少数系统真正需要

每多一个 9,容错时间就除以 10,而成本远不止乘以 10。 几个关键的现实约束:

  • 99.99% 意味着全年只有 52 分钟。 一次「发现 + 拉群 + 定位 + 回滚 + 验证」的常规故障处理就是 20~30 分钟。也就是说,全年只能出两次故障,而且必须处理得很快。
  • 99.999% 意味着全年 5 分钟。 人工介入在这个量级下根本来不及------从收到告警到人打开电脑就超预算了。必须全自动故障转移、自动熔断、自动切流,人只能事后复盘。
  • 发布本身就在消耗预算。 一次滚动发布如果有 30 秒的连接抖动,一个月发 10 次,就是 5 分钟------已经超过 99.99% 的月度预算(4.32 分钟)。所以高可用系统必须做到发布无损(优雅摘流量、连接优雅关闭)。

四、最容易被忽略的事:串联的乘法效应

这是微服务架构下最重要的可用性认知:

串联的衰减比直觉严重得多。以下是每个环节都做到 99.9% 时,整体可用性随依赖数量的变化:

强依赖数量 整体可用性 年停机
1 个 99.900% 8.76 小时
3 个 99.700% 1.09 天
5 个 99.501% 1.82 天
10 个 99.005% 3.63 天
20 个 98.019% 7.23 天
50 个 95.121% 17.81 天

结论很残酷 :一条请求链路上如果有 10 个强依赖(网关 + 鉴权 + 订单 + 库存 + 风控 + 优惠 + 支付 + MySQL + Redis + MQ),每个都做到 99.9%,整体只有 99%------连 3 个 9 都达不到。而要让整体达到 99.99%,每个环节需要做到 99.999%,这在工程上不现实。

所以提升整体可用性的正确路径不是「让每个服务更可靠」,而是减少强依赖的数量

依赖类型 定义 处理策略
强依赖 挂了请求必然失败(订单 → MySQL) 必须冗余、必须高可用
弱依赖 挂了可以降级(订单 → 推荐服务) 熔断 + 降级,从可用性公式中剔除

一次认真的「强弱依赖梳理」评审,对可用性的提升往往超过堆一倍机器。

4.1 并联冗余有个前提:故障必须独立

1 − ( 1 − A ) n 1 - (1-A)^n 1−(1−A)n 这个公式成立的前提是各副本故障相互独立。现实中往往不独立:

相关故障来源 后果
同一机房 断电/断网,所有副本一起挂
同一份代码 一个 NPE bug,所有副本同时崩
同一配置中心 一次错误的配置推送,全军覆没
同一下游依赖 都连同一个 DB,DB 挂了全挂

所以数学计算出的可用性是理论上限 。真实世界里,绝大多数重大故障都是相关故障(correlated failure) ------这也正是多可用区、多地域部署的意义:它买的是「故障域隔离」,而不是单纯的副本数量

同理,「同一份代码的 100 个副本」在代码 bug 面前的可用性等于 1 个副本。这就是灰度发布存在的理由。


五、SLI / SLO / SLA 与错误预算

这三个词经常被混用,但含义完全不同:

概念 全称 含义 例子
SLI Indicator 实际测量的指标 上月非 5xx 且 P99<500ms 的请求占比 = 99.97%
SLO Objective 内部目标 目标 ≥ 99.95%
SLA Agreement 对外合同承诺,违约要赔钱 承诺 99.9%,未达标赔偿 10% 服务费

关键实践:SLA 必须明显低于 SLO。对外承诺 99.9%,内部目标定 99.95%,这中间的差额就是你的安全垫。如果 SLA 和 SLO 相等,那意味着任何一次波动都会直接触发赔偿。

5.1 错误预算(Error Budget)------ 最实用的管理工具

Error Budget = 1 − SLO \text{Error Budget} = 1 - \text{SLO} Error Budget=1−SLO

SLO 定 99.9%,则每月的错误预算是 43.2 分钟。这个数字的用法是:

预算状态 行动
预算充足 可以快速上线新功能、可以做混沌工程演练、可以承担一定风险
预算耗尽 冻结功能发布,全员转向稳定性工作,直到下个周期预算重置

这个机制的真正价值在于------它把「稳定性」和「迭代速度」这个永恒的矛盾变成了一个可量化、可仲裁的数字。业务方要求快速上线、SRE 要求稳定,双方不需要吵架,看预算余额就行。预算没了,规则说停就停;预算还有,就放手迭代。

它同时也暗示了一个反直觉的观点:可用性不该无限追求。 如果一个季度下来错误预算完全没用掉,说明你在稳定性上过度投入了,那些资源本可以用于业务创新。


六、工程实践建议

6.1 不要盲目追求高 9,先算业务账

定 SLO 的正确方式是回答两个问题:

  1. 停机一分钟的业务损失是多少?(营收损失 + 品牌损失 + 赔偿)
  2. 多加一个 9 的工程成本是多少?(多机房、冗余资源、自动化建设、人力投入)

当边际成本超过边际收益时就该停。绝大多数业务系统的合理答案是 99.9% ~ 99.99%,而不是 5 个 9。

6.2 分级定义,不要全站一个标准

分级 系统 SLO
P0 核心 下单、支付、登录 99.99%
P1 重要 商品详情、购物车 99.95%
P2 一般 评论、推荐、营销页 99.9%
P3 内部 后台管理、报表 99%

6.3 其他要点

  • 按用户感知定义 SLI,不要用服务器指标。CPU 100% 但请求都成功,那就是可用的;CPU 10% 但全部超时,那就是不可用的。
  • 发布必须无损:优雅摘流量 → 等存量请求处理完 → 停机。你之前研究的连接池 TTL 与服务端 keepalive 配合,就是无损发布的一环。
  • 预案要演练。没演练过的预案在故障时等于不存在------故障现场没人有心情读文档。
  • 定期混沌演练,主动注入故障验证冗余是否真的生效。很多「双活」架构在真正断网时才发现从来没切换成功过。

小结

问题 答案
可用性怎么定义 推荐请求维度:成功请求数 / 总请求数,且必须包含延迟条件(慢等于不可用)
另一个等价公式 可用性 = MTBF /(MTBF + MTTR)
该往哪投入 压缩 MTTR,尤其是 MTTD(发现时间),性价比远高于追求零故障
99.9% 意味着 年停 8.76 小时,月停 43.2 分钟
99.99% 意味着 年停仅 52.56 分钟,全年只允许出两次故障,发布必须无损
99.999% 意味着 年停 5.26 分钟,人工介入来不及,必须全自动故障转移
最容易被忽略的 串联乘法效应------10 个 99.9% 的强依赖串起来只有 99%
提升可用性的正确路径 减少强依赖数量(弱依赖化 + 熔断降级)> 让每个服务更可靠
冗余的隐含前提 故障相互独立。相关故障(同机房/同代码/同配置)是数学公式失效的主因
最实用的管理工具 错误预算:预算充足则放手迭代,耗尽则冻结发布

一句话总结:可用性不是技术指标,而是一个商业决策。定 SLO 的过程本质是在回答「为了少停机一分钟,你愿意花多少钱」,而不是「技术上能做到几个 9」。

相关推荐
程序员-Benothing1 小时前
Linux 软件包管理:yum / apt / dnf 命令使用全解析
linux·运维·服务器
奇牙coding1231 小时前
GPT-5.5 升级 GPT-5.6 接入指南:流式调用配置与常见问题
java·网络·gpt·ai
stellanke2 小时前
Linux网络编程实战2:TCP Socket 基础与实践
linux·网络·c++
竣达技术2 小时前
UPS 供电风险保护方案网络远程控制:免代理 SSH/Telnet UPS 安全关机方案
网络·安全·ssh
芯飞云2 小时前
芯飞云服务器日常使用体验:从配置选型到实际负载的技术分析
运维·服务器
小程序设计2 小时前
工业园区、企业、公司网络规划与设计
网络
Splashtop高性能远程控制软件2 小时前
AI 辅助端点运维先接手补丁分级、合规可视和同台处置
运维·网络·人工智能·自动化·远程工作·splashtop
严谨的麻辣烫2 小时前
AI Agent为什么越来越需要固定出口IP?从API白名单到生产环境网络管理
服务器·网络·tcp/ip·代理服务器
POMAGTOR2 小时前
【5G 通讯 POGOPIN 弹簧顶针连接器解决方案】
网络·嵌入式硬件·5g