质量属性
非功能需求是写成数字的质量属性
功能清单决定系统「做什么」,非功能需求决定「做得怎么样」,别名叫质量属性(Quality Attributes)。 功能缺了系统能跑,非功能缺了系统不能用;验收方式也不同——功能可以勾选,质量必须是刻度。 「要稳定」这类形容词没有刻度,验收时产品拿它说慢、研发拿它说没挂,无数字则验收即扯皮。 常用五个维度记忆:快(性能)、稳(可用性)、扩(可扩展性)、安(安全性)、改(可维护性)。
业界权威分类是 ISO/IEC 25010 产品质量模型,2023 修订版从八个特性扩到九个:新增 safety (人身安全,区别于 security 信息安全),usability 改名 interaction capability,portability 改名 flexibility。 「扩」在其中并非一等特性,更多是架构属性而非产品交付属性。
性能验收写百分位,不写平均值
平均值掩盖尾巴:平均延迟 80ms 的服务,可能同时有 1% 的请求拖到 800ms,而用户感受到的恰恰是尾巴。 P99(99th percentile latency,第 99 百分位延迟)的含义是一百次请求里九十九次必须落在该阈值内。 完整的性能验收是成对的:延迟(如 P99 < 200ms)加吞吐(如每秒 2000 笔), 只写延迟的话,压低并发就能「达标」。
见:Service Level Objectives - Google SRE Book
可用性的几个 9 是一张停机预算表
把可用性按一年 8760 小时摊开:两个 9(99%)允许停 87.6 小时,三个 9 停 8.8 小时, 四个 9 剩 53 分钟,五个 9 只剩 5 分钟。每多一个 9,允许停机时间砍掉十倍。 「几个 9」不是口号,是预算表——预算花完,当年可用性即告破。 签下几个 9 之前先换算成停机预算,再问业务量撑不撑得起。
见:Uptime and downtime availability calculator
SLI 是针、SLO 是红线、SLA 是合同
把「稳」写成数字需要三个配套概念。SLI(Service Level Indicator,服务水平指标)是那根针, 只测量不承诺,最常见形式是成功请求数 ÷ 总请求数;针必须钉在单一具体路径(如结账接口), 混入健康检查会把失败率拉绿。定义「成功」时把慢请求直接计入失败——慢的请求等于不可用, 用户不会区分「挂了」和「转圈 10 秒」,可用性数字也不该区分。SLO(Service Level Objective,服务水平目标)是对内红线, 规定针停在哪里(如 99.9%);其下方是错误预算(Error Budget)= 1 − SLO, 额度没花完可正常发版试新功能,花光就该关发布闸门——数字本身不产生行为,配套策略才产生。 SLA(Service Level Agreement,服务水平协议)是对外合同,破了按条款赔钱。 落地顺序不可反:先立针,再画线,最后签合同;合同先盖章、针还没立,事后只能补形容词。
SLA 必须比 SLO 松一截,这是数学必然而非保守习惯:端到端可用性约等于各串联依赖可用性之积, 三个 99.9% 的依赖串联只剩 99.7%,对外承诺天然被依赖链封顶,松出的差额才容得下测量误差与突发。 另一个实务差异:错误预算的计量窗口业界常用 28/30 天滚动窗口,按自然年换算停机时长是教学化处理。
见:Service Level Objectives - Google SRE Book
每多一个 9 成本跳一个数量级
从三个 9 到四个 9,允许停机时间从 8.8 小时收窄到 53 分钟,为此要上多活架构、自动故障转移、 全链路压测,人、机器、演练成本按数量级上涨,不是线性加一截。 多活防的是整个地域不可用(机房断电、光缆挖断、区域云故障),单地域内的问题同城双活就能扛, 业务量撑不起时「同城双活加异地冷备」是更诚实的档位。
反直觉的结论是少一个 9 往往才是正确选择:先问能为可靠性付多少钱、业务量撑不撑得起,再决定写几个 9—— 9 越多不代表越专业,只代表停机预算越贵。预算花不完同样是失败:长期大量剩余说明系统过度可靠, 多花的钱本可以换成发版速度与新功能;SLO 定得过紧则预算频烧、触发功能冻结。 所以 SLO 不是纯技术指标,是产品与研发的谈判产物,SRE Workbook 建议目标不要明显高于现状。
见:Implementing SLOs - Google SRE Workbook
P99 全线达标不等于用户不慢:尾部放大
P99 达标时单个用户会话仍可能很慢。一次页面加载发出 30 个请求,全部落在 P99 以内的概率是 0.99³⁰ ≈ 74%,即每四个会话仍有一个碰到慢请求。微服务链路放大得更狠:请求穿过 100 个独立实例时, 至少踩到一个慢节点的概率是 1 − 0.99¹⁰⁰ ≈ 63%——部分达标相乘之后整体不达标, Dean 与 Barroso 在 The Tail at Scale(2013)里称之为尾部放大(tail amplification)。 验收时「每个服务 P99 < 200ms」不构成「页面 200ms」的证据链;面向用户会话的 SLO 用错误率(慢会话占比)比用百分位诚实。
见:The Tail at Scale - Google Research
错误预算告警告的是烧钱速度,不是余额
在「月可用性 ≥ 99.9%」上直接设阈值告警,等于订了一份月度事故总结——预算烧完才响; 按原始错误率(红线 0.1%)设阈值又会被正常业务波动吵死。 SRE Workbook 的解法是多窗口多燃烧率(multiwindow multi-burn-rate)告警:不告余额,告烧钱速度。 经典档位:1 小时窗口烧率 14.4×(照此速度约两天烧完 30 天预算,触发 page)、6 小时窗口 6×、 3 天窗口 1×(正好在窗口末烧完,降级为 ticket),每个档位再配一长一短双窗口确认以滤掉瞬时毛刺。 定完 SLO 数字离「SLO 在生产可用」还差这一整套告警工程,Prometheus 生态的 sloth 就是为生成这套规则而生。
见:Alerting on SLOs - Google SRE Workbook
服务端 SLI 有观测盲区
服务端 SLI 从日志统计「成功响应 ÷ 总响应」,分母只有到达服务端的请求——DNS 解析失败、 TLS 握手被运营商劫持、CDN 边缘节点故障、移动网络断连的请求根本没到服务器,不进分母。 结果服务端报表 99.95%,用户实测可能只有 99.5%,误差一个数量级。 SLO 承诺的对象是用户体验,SLI 测量的位置却在服务端,这个断层是所有 SLO 体系的固有缺口; 缓解手段是从客户端补测:RUM(Real User Monitoring,真实用户监控)或合成探针(synthetic probes)。 定义任何 SLI 之前先问:这个指标的分子分母,各自覆盖了用户路径的哪一段?
监控先补齐四个黄金信号
新服务的监控面板先覆盖延迟(latency)、流量(traffic)、错误(errors)、饱和度(saturation, 队列堆积、连接池占满、磁盘水位)四项。SRE Book 认为它们覆盖了绝大多数用户可感知的故障模式, 精细化的自定义面板应建立在这四项齐全之后。