质量属性与场景:把「要快、要稳」变成可验收的需求

"系统要快、要稳、要好改"不是需求,是愿望。质量属性(quality attribute)必须写成场景(scenario),即"在什么情况下、发生什么事、系统如何响应、用什么数字验收"。写不出数字的场景,验收时一定吵架。

六要素场景模板

一条合格的质量属性场景包含六部分,缺任何一部分都会留下扯皮空间:

来源(source)      :谁发起 —— 用户、定时任务、运维、攻击者
刺激(stimulus)    :发生什么 —— 提交订单、磁盘写满、并发翻倍
制品(artifact)    :作用于谁 —— 下单接口、订单库、网关
环境(environment) :什么状态 —— 正常负载、峰值、降级中
响应(response)    :系统做什么 —— 拒绝并提示、切换备用链路、限流
响应度量(measure) :用什么数字判断 —— TP99、恢复时间、丢失条数

把"要快"填进模板:峰值环境下,用户提交下单接口,系统在 1 秒内返回订单号,其中 TP99 ≤ 800ms、TP999 ≤ 1.5s,错误率 < 0.1%。这才叫需求。

常见质量属性与可验收指标

质量属性场景化指标示例常被误当成指标的写法
性能(performance)峰值 TP99 ≤ 800ms,QPS ≥ 3000"响应要快"
可用性(availability)单机房故障 5 分钟内自动切流,月度可用性 ≥ 99.95%"要高可用"
可修改性(modifiability)新增一个支付渠道工作量 ≤ 3 人日,改动不超过 2 个模块"要好扩展"
可测试性(testability)核心聚合的单元测试可脱离数据库运行,单测覆盖分支 ≥ 80%"要能测"
可部署性(deployability)单服务灰度发布 ≤ 10 分钟,回滚 ≤ 3 分钟"要能快速上线"
安全性(security)越权访问在网关被拦截,审计日志留存 180 天"要安全"
可观测性(observability)一次线上报错 5 分钟内定位到具体服务与接口"要有监控"
成本(cost)单万单成本 ≤ 0.8 元,扩容 1 倍容量成本增幅 < 1.2 倍"要便宜"

注意:限流、熔断、降级的具体实现属于弹性设计专题(第 16 章),可观测性体系建设属于第 17 章。本章只解决"怎么把愿望写成可验收的句子"。

场景 → 指标 → 验收 三段式

写完后自检三步,任何一步断裂都说明场景不合格:

步骤要回答的问题反例
场景谁在什么情况下触发"系统应该很快"
指标用什么数字衡量、在哪个分位"平均响应 100ms"
验收谁来测、怎么测、不达标怎么办"上线后观察一下"

验收方式要具体到可执行:

验收方式 A(压测):用 1:9 读写比的脚本打到 3000 QPS 持续 10 分钟,
                    观察 TP99 与错误率,连续 3 轮达标即通过
验收方式 B(演练):主动 kill 主库所在可用区,记录自动切流耗时
验收方式 C(改造):在隔离分支上实现"新增支付渠道",统计最终 diff 的模块数与工时

平均值的陷阱:延迟分布是长尾的,平均值 100ms 可能对应 TP99 = 3s。任何性能类质量属性都必须带分位(percentile),否则可以被几个慢请求或几个快请求轻易操纵。

质量属性之间会互相拉扯

提升 A通常牺牲 B具体表现
性能(缓存、本地状态)一致性、可修改性缓存让读到旧值;本地缓存让改数据结构变难
可用性(多副本、异步)一致性、成本副本滞后;机器数量翻倍
可修改性(抽象层)性能、可理解性每层转发带来开销;调用链变长
安全性(加密、审计)性能、可部署性加解密损耗;密钥管理增加发布步骤
可测试性(依赖注入)上手成本新人需要先理解抽象与装配

取舍要有依据:先排出优先级(业务上哪个属性不可让步),再定可牺牲的余量(最多慢多少、最多不一致多久)。这个排序应该写进架构决策记录,而不是留在某个人脑子里。

从质量属性到架构手段

质量属性决定结构,而不是反过来。常见的映射:

可修改性  → 按业务能力划分模块,依赖倒置,接口定义在调用方(第 04 章)
可用性    → 无状态化、多副本、故障隔离与降级(第 16 章)
性能      → 减少跨边界调用、批量与异步化、数据就近(缓存细节见 system-design 第 16 章)
一致性    → 数据所有权单一、事件与事务边界(第 10、14 章)
可观测性  → 统一 trace 上下文、结构化日志、指标埋点作为验收项(第 17 章)
可部署性  → 部署单元粒度、配置外置、向后兼容的接口演进(第 18 章)

反向也成立:如果某个质量属性没有对应到任何结构措施,它就不会被实现。"要高可用"却不做无状态化、不给数据副本,就只是一句口号。

把质量属性写进需求文档

推荐在需求模板里固定留一节,每个关键用例配一张表:

用例:用户提交订单
功能:校验库存、生成订单、发起支付
质量场景:
  1) 正常:峰值 3000 QPS,TP99 ≤ 800ms,错误率 < 0.1%
  2) 过载:QPS 到 6000 时,保护 80% 的正常用户,多余请求快速失败(≤ 200ms 返回)
  3) 故障:支付回调延迟 30 分钟内到达,订单最终一致,不产生重复扣款
  4) 变更:新增支付渠道 ≤ 3 人日,不改动订单核心校验逻辑
验收:压测脚本 + 演练剧本 + 隔离分支实测,数据留档

这张表可以直接变成测试用例与监控告警的阈值来源,一举三得。

常见误区

  • 只写平均延迟:没有分位的性能指标在长尾场景下毫无约束力。
  • 把 SLA 当内部指标:对外承诺 99.9% 不等于内部每个依赖都能用 99.9%,依赖串联会放大不可用。
  • 所有属性都要最好:等于没有优先级,最终每个都做不到位。
  • 用"高并发"当需求:没有业务动作和读写比的并发数字无法推导结构。
  • 验收推给上线后:场景写完就该确定测法,否则上线时只能靠感觉。

小结:把愿望变成需求的唯一路径是六要素场景 + 分位指标 + 明确验收方式。写完后检查质量属性之间是否优先级明确、是否有对应的结构手段;没有结构手段支撑的质量属性等同于没写。

笔记加载中…