做运维、做架构、写SLA,绕不开一个词:可用性。前阵子有朋友问我:"合同上写可用性99.99%,一年到底能挂多久?"我说52分钟出头。他又问:"那要是99.999%呢?"我说一年只能挂5分钟多点。他愣了一下:"就差一个9,怎么差这么多?"这个问题其实特别典型。很多人对"几个九"的概念就停留在"数字越大多越好",但真要回答"按年、按月、按周、按天分别允许停机多久",能立刻算清楚的人并不多。
今天这篇文章不聊架构,也不讲监控工具,就专门把"各个九对应停机时间"这笔账彻底算明白。我会把从99%到99.99999%这六七个常见档位,分别按年、月、周、天四个粒度拆开,告诉你每个档位到底允许系统挂多久。这些数值不是用来背的,是用来直接落地到SLA制定、告警阈值设计和故障复盘里的。写SLA、做容量规划、定应急预案的人,建议把这篇收藏起来当工具表用。
1. "几个九"到底在说什么:先把公式吃透
很多新人会把"99.99%可用"理解成"系统特别稳定",这句话没错,但不够精确。可用性的定义不是"不出故障",而是"在单位时间内正常服务的时间占比"。严格一点,它的计算口径通常是:
可用性 = 正常运行时间 / (正常运行时间 + 停机时间)如果只谈百分比,那它的反面叫"不可用率":
不可用率 = 1 - 可用性所以"四个九"等于99.99%,对应的不可用率是0.01%,也就是0.0001。记住"不可用率"这个概念,后面所有的停机时间计算全靠它。
1.1 可用性不是"稳定",而是"故障时间的占比上限"
举个生活化的例子。小区门口有家便利店,承诺"每天营业12小时",一年365天都开门。如果这个店一年里因为进货、盘库、断电累计关了4.38小时,那它的"年度可用性"大约就是99.9%——因为一年8760小时里它只关了4.38小时。这个店不能说"我从来没坏过",但客户基本感知不到问题。换成你的业务系统也一样:可用性只约束"挂多久",并不约束"挂几次"。
很多刚入行的朋友会混淆"可用性"和"可靠性"。可靠性指两次故障之间的平均间隔,也就是MTBF;可用性则是MTBF和MTTR(平均修复时间)共同决定的。公式是MTBF/(MTBF+MTTR)。一个系统可能经常抖,但每次几十秒就恢复,那它的可用性不一定差;反过来,一个系统一年只挂一次,但一次挂两小时,可用性可能只有99.9%左右。所以优化可用性,不光要减少故障次数,还要缩短每次故障的恢复时间。这一点在后面按天算预算的时候,会体现得特别明显。
1.2 每多一个九,不是多一点点,而是严格十倍
这里有个最容易忽略的地方:99%和99.9%差多少?不是字面上差0.9个百分点,而是"不可用率"从1%降到了0.1%,停机时间预算直接缩到十分之一。同理,99.99%比99.9%严格10倍,99.999%比99.99%又严格10倍。用大白话说:四个九是一年挂52分钟多,五个九是一年挂5分钟出头。每加一个九,允许挂的时间直接砍掉一个数量级。
我见过不少团队定目标时很随意,张嘴就是"我们要做到99.999%"。等我把对应的时间预算摊出来,他们才意识到一年只能挂5分钟出头,一个月预算才25秒。所以选可用性等级不能凭感觉,要先用时间预算倒推,看你的故障恢复水平能不能兜住。各档位的不可用率差异,看下面这张表:
| 可用性等级 | 不可用率 | 对应含义 |
|---|---|---|
| 99%(两个九) | 1% | 每年有1%的时间不可用 |
| 99.9%(三个九) | 0.1% | 比两个九严格10倍 |
| 99.99%(四个九) | 0.01% | 比三个九严格10倍 |
| 99.999%(五个九) | 0.001% | 比四个九严格10倍 |
| 99.9999%(六个九) | 0.0001% | 比五个九严格10倍 |
这10倍的差距,是理解所有停机时间对照表的基础。下面开始看具体数字。
2. 按年算停机时间:签合同、写SLA最常用的口径
先看最常用的"年度"口径。这里以365天作为一年,也就是8760小时。网上很多SLA模板里写"99.99%对应每年不超过52.6分钟",就是这么算出来的。
2.1 全年可用性对照表:一年到底能挂多久
按365天一整年算,各档位允许的停机时间如下:
| 可用性等级 | 一年不可用时间 | 换成更直观的单位 |
|---|---|---|
| 99%(两个九) | 87.6小时 | 约3天15小时36分 |
| 99.9%(三个九) | 8.76小时 | 约8小时45分36秒 |
| 99.99%(四个九) | 52.56分钟 | 约52分33秒 |
| 99.999%(五个九) | 5.256分钟 | 约5分15秒 |
| 99.9999%(六个九) | 31.536秒 | 约31.5秒 |
| 99.99999%(七个九) | 3.154秒 | 约3.2秒 |
这张表建议直接贴在监控大屏旁边。不是因为好看,而是因为它能把抽象目标量化到"一年最多挂多久"。比如运营告诉你上个季度挂了2次,每次20分钟,加起来40分钟,一对比发现已经超过99.99%的年度预算了,可这个季度还有一个月没走完,后面再出一次事故,全年就守不住。这种"预算快用完"的紧迫感,只有量化之后才出得来。
2.2 年度口径的局限性:它是个"秋后算账"的指标
年度可用性适合签合同、做年度总结,但它有一个明显问题:粒度太大,反应太慢。等你在年度面板上看到可用性跌破目标,往往事故已经过去很久,预算早就超支了。所以工程上的做法是把它拆成更小的窗口来盯:季度、月度、周、甚至天。把"年、月、周、天"四个维度都列出来,就是为了适配不同场景下的管理粒度。
另一个容易踩的坑是"一年按多少天算"的口径问题。有的协议按365天,有的按365.25天,甚至有人图省事按360天。举个例子,99.99%在365天口径下是52.56分钟,按365.25天算是52.60分钟,差异不到1秒;但如果你用360天,算出来就是51.84分钟,能差出40多秒。SLA合同里这类口径差异一旦较真,对账时会很麻烦。我自己早期做合同评审时没注意分母口径,事后核对数据才发现定义不一致,后来凡是涉及可用性的条款,第一件事就是确认周期基准。
3. 按月、按周算:SLO预算怎么分才合理
年口径是"秋后算账",那平时看什么?看月和周。月和周的粒度正好匹配大多数团队的发布节奏和SLO考核周期。
3.1 自然月口径:别忽略30天和31天的差别
先看按"月"算。为了方便,很多工具和文档会统一按30天即720小时来算,这样得出的值是一个"平均月"的预算。实际自然月有28/29/30/31天,预算会差几个百分点,但对大多数业务来说,用30天口径做估算已经足够了。
按月计算,各档位对应关系如下(按30天一月的口径):
| 可用性等级 | 一月不可用时间 | 换成更直观的单位 |
|---|---|---|
| 99%(两个九) | 7.2小时 | 7小时12分钟 |
| 99.9%(三个九) | 43.2分钟 | 43分12秒 |
| 99.99%(四个九) | 4.32分钟 | 4分19秒 |
| 99.999%(五个九) | 25.92秒 | 约26秒 |
| 99.9999%(六个九) | 2.592秒 | 约2.6秒 |
| 99.99999%(七个九) | 0.2592秒 | 约0.26秒 |
这个维度的核心用途,是跟"月度SLO"挂钩。比如你和客户签的SLA是月度99.9%,那你这个月所有发布、变更、故障导致的不可用时间加起来,预算就是43.2分钟。很多人没有"月度预算"意识:月初一个功能上线,灰度发布卡了半小时;月底再出个小故障20分钟,回头一看,这个月可用性已经不到99.9%了。等月底复盘才发现,问题不是一次重大事故导致的,而是一个个"看似可接受的变更"把预算吃光了。
3.2 周维度:发布窗口和维护窗口是预算消耗大户
把窗口再缩小到一周(7天=168小时),各档位对应关系如下:
| 可用性等级 | 一周不可用时间 | 换成更直观的单位 |
|---|---|---|
| 99%(两个九) | 100.8分钟 | 1小时40分48秒 |
| 99.9%(三个九) | 10.08分钟 | 10分4.8秒 |
| 99.99%(四个九) | 60.48秒 | 约1分钟 |
| 99.999%(五个九) | 6.048秒 | 约6秒 |
| 99.9999%(六个九) | 0.6048秒 | 约0.6秒 |
| 99.99999%(七个九) | 0.06048秒 | 约60毫秒 |
周预算的实战意义主要在发布和维护。举个例子,你承诺99.99%可用性,一周总预算只有60秒。一次常规发布如果涉及滚动重启,假设每台机器重启要10秒,你有8台机器,只要不是真正的无缝滚动,每台停机10秒就已经80秒,这一周还没等流量高峰到来,可用性预算就已经超了。所以团队做发布方案时,一定要先算"这轮变更会吃掉多少停机预算",再决定要不要选在低峰期、要不要用蓝绿发布或金丝雀发布来规避传统重启。这在追求高可用性系统的团队里,是发布评审的必答题。
4. 按天算:监控频率与告警阈值的一场博弈
日维度是最好理解的:一天就是24小时、1440分钟、86400秒。但也是最能让人清醒的维度,因为你会发现很多"看起来很高"的可用性目标,折成一天根本没剩多少容错空间。
4.1 日维度对照表:一天能挂几秒
按24小时一天计算,各档位对应关系如下:
| 可用性等级 | 一天不可用时间 | 换成更直观的单位 |
|---|---|---|
| 99%(两个九) | 14.4分钟 | 14分24秒 |
| 99.9%(三个九) | 86.4秒 | 1分26秒 |
| 99.99%(四个九) | 8.64秒 | 接近9秒 |
| 99.999%(五个九) | 0.864秒 | 不到1秒 |
| 99.9999%(六个九) | 0.0864秒 | 约86毫秒 |
| 99.99999%(七个九) | 0.00864秒 | 约8.6毫秒 |
很多团队看到"99.999%一天只能挂0.864秒"时,第一反应是"这不可能"。确实,如果你还在用"每隔60秒探活一次、连续失败2次才告警"的监控方案,探测周期本身就已经远超日预算了。这也是为什么真正的五个九系统,必须有非常强的冗余和自动故障转移能力,而不是靠人去扛。人肉值班的极限,和五个九的预算根本不在一个量级。
4.2 用日预算倒推监控频率和告警阈值
这里有个实操技巧:拿日预算去倒推监控频率。假设你的目标是99.99%,一天只能挂8.64秒,那你的探活周期至少要小于8.64秒,否则一次故障从发生到被探活发现,时间就已经用掉一大半。更进一步,告警链路本身也有延迟:Prometheus拉取一次要几秒、告警规则评估要几十秒、值班人看到通知再登录服务器,这几个环节走完,十分钟就过去了。如果你的系统不具备自动恢复或自愈能力,单靠"探活+人工"想守住四个九以上,基本是白日梦。
正因为这样,很多高可用性系统在设计时会把"无人干预的故障转移时间"当成关键指标。数据库主从切换、负载均衡摘流、多可用区调度,要的就是把RTO(恢复时间目标)压缩到分钟级甚至秒级。我见过一个支付类业务,对外宣称99.99%,但他们做数据库切换演练时,RTO目标压在30秒内。为什么?因为一天只有8.64秒预算,但报警发现、人员确认、决策切换这些环节还要占时间,只能靠自动切换把核心恢复动作压到极致,才有希望在预算内兜住故障。
5. 从表格到SLO管理:这套数值怎么落地
上面这些表,如果你只当"知识"看看,价值不大。真正的用法是把它落成SLO、监控策略和流程规范。
5.1 先选SLI,再谈SLO:可用性到底按什么算
"可用性到底按什么算"在工程上必须先定清楚。我见过团队把SLO写成"系统可用性99.9%",但没人规定这个可用性是用HTTP探活成功率、请求错误率、还是核心接口的延迟达标率来测量。结果就是事故复盘时,研发说"服务没挂,只是部分请求超时了",测试说"探活一直是通的",两边各说各话。先定义SLI(服务等级指标),再定义SLO(服务等级目标),顺序一定不能反。
三种最常见的SLI口径:
- 请求成功率:成功请求数除以总请求数,适合对外API和Web应用。
- 探活可用性:按固定周期探测目标服务是否可访问,适合网络设备和基础组件。
- 延迟达标率:例如P99延迟小于200毫秒的请求占比,适合对性能敏感的业务。
不同口径算出来的"可用性"可能差很多。比如一个服务有1%的请求会超时,但探活点只探测首页,探活结果可能一直是200,你的"可用性"看起来是99.9%,实际上用户体验已经很差了。所以定SLI时,要选最贴近用户真实感受的指标,而不是选最容易测的指标。
5.2 错误预算告警:别等超了再报警
SLO定下来之后,错误预算(Error Budget)就是"允许出错的额度",也就是前面算的那些停机时间或不可用比例。团队里最常见的错误是:只放一个"本月可用性"曲线,等到它跌破目标线才告警。但这个指标是滞后指标,等你看到的时候,事故已经造成损失了。
我建议的错误预算告警方式分三级:
- 第一级:预算消耗速率告警。如果按当前消耗速度推算,月底会超过可用性目标,就提前告警。这能在故障发生早期介入,而不是月底秋后算账。
- 第二级:瞬时可用性告警。5分钟或10分钟窗口内的可用性跌破某个应急预案门槛,立刻触发高优告警,不管本月总预算还剩多少。
- 第三级:单一事件消耗告警。任何一次故障把月度预算消耗超过一定比例,比如10%,就立刻触发复盘,不用等到月底。
这里给一个计算示例:月度目标99.9%,月预算43.2分钟。某次故障时长6分钟,那它已经消耗了当月预算的6除以43.2约等于13.9%。如果这个月出现7次同样规模的故障,月度目标铁定保不住。用这个比例作为"故障严重度"的判定依据,比单纯按持续时间长短定性要更贴近实际用户影响,也更方便向非技术同事解释。
6. 常见误解与排查技巧实录
从事稳定性和架构工作久了,会发现同样的错误反复出现。这里列几个我踩过的坑,基本都是真实发生过的事。
6.1 四个高频误解
- 误解一:把99.999%理解成"一年只能挂5分钟出头,平均每天能挂几十秒"。实际上按日口径算,五九只有0.864秒,年度和日度是两个完全不同的量纲,不能简单除以365就完事。
- 误解二:以为99.99%比99.9%"只是多了0.09个百分点"。错,这0.09个百分点对应的是不可用率缩到十分之一。所以从三个九提到四个九,投入的资源和付出的努力往往要翻好几倍。
- 误解三:只盯着"停机时间"而忽略"降级服务"。比如你把首页缓存开了,用户能看到页面,但下单接口超时,严格来说系统"不可用"了吗?这取决于SLI定义。如果SLI只统计HTTP 200,那降级可能完全不可见,用户却已经在骂了。
- 误解四:用年目标倒推日常告警。这样导致事故发生后两三个月才意识到预算超支,再想补救已经晚了。正确的做法是把预算切到月度、周度,甚至用滚动窗口来管理。
6.2 排查问题时我会逐条核对
每次做完故障复盘,我习惯拿这几条检查方案:
- 故障持续时间是多少?换算成对应的月度或年度预算消耗百分比。
- 监控系统是多久后发现异常的?这个"发现延迟"对后续处理影响有多大?
- 自动恢复机制有没有生效?如果没有,人工介入花了多久?
- 当前可用性目标下的日预算是多少?故障恢复时间RTO有没有超出预算?
- SLI口径是不是足够贴近用户真实体验?
这些核对项能帮你在事故后快速定位:到底是稳定性问题,还是监控灵敏度问题,或者是流程协作问题。很多时候你以为是在治理技术债,实际需要治理的是发现链路和响应链路。比如有一次故障持续了15分钟,正好卡在99.99%的日预算边缘,复盘时发现其中11分钟都耗在"告警发出但没人确认"上,真正的修复操作只花了4分钟。那这次事故的核心问题不是代码,而是告警触达和值班机制。
7. 一点落地的个人体会:先算账,再定架构目标
这些年做稳定性治理,我最大的体会是:很多团队不是没有技术能力,而是没有先做算术题。定99.9%还是99.99%,不应该靠拍脑袋,而要看业务能接受多久不服务,以及团队有没有能力把故障恢复时间压到那个量级。算清楚年、月、周、天四个维度的停机预算,是聊高可用性系统所有话题的起点。没有预算概念的高可用性设计,就像没有上限的信用卡,刷爆是迟早的事。
我还养成了一个习惯:每接一个新系统,第一周就把它的SLO拆成一张表贴到团队空间里——季度预算多少分钟、月度多少、单周多少、单日多少秒;然后在监控系统里加上"本月已消耗错误预算"这个指标。有这个数字在,每次有人提"要不要临时加个变更"的时候,先看一眼预算剩余,很多事情自然就有了结论。预算充足时,快速试错是合理的;预算告急时,一切变更都要走更重的评审流程。
最后再分享一个小技巧:不要把可用性目标只写成"一年X个九",而是在团队内部把目标拆成"本月错误预算剩余X分钟"。目标太抽象,团队没有体感;预算太具体,每个人都能理解还剩多少容错空间。这一张对照表加一个预算面板,可能是我做稳定性治理以来觉得投入产出比最高的两样东西。