【软件系统架构】系列十三:系统架构设计——质量属性场景(QAS)

一、QAS 六要素(精确定义与撰写要点)
QAS 模板:刺激源 → 刺激 → 环境 → 制品 → 响应 → 响应度量
写 QAS 时的原则:
-
刻画明确的主体和触发条件(谁/什么触发了什么),避免模糊词(”很快””高可用”)。 -
环境要写清楚(正常、高峰、降级、离线、网络抖动等)。 -
响应要描述系统行为(而不是实现细节)。 -
响应度量必须可观测(具体数值、分位、时间窗、容忍)–这是可验证性的关键。 -
同一个 QAS 同时写出SLI(观测指标)与SLO(目标),并绑定验证手段(测试/演练)与回退/降级策略。
常用约定:用绝对量(ms、分钟、req/s、%)或分位(P95/P99),写上窗口(例如”过去 5 分钟 P95 < 200ms”)。
二、QAS 撰写模版(YAML)
id: QAS-xxx
name: 描述性标题
stakeholder: 业务/运维/安全
stimulus_source: "谁触发(user/payment-gateway)"
stimulus: "触发事件"
environment: "正常/高峰/降级/离线/网络抖动"
artifact: "系统/子系统/服务/接口"
response: "系统应如何行为(含降级/重试)"
response_metrics:
- sli: "P95_latency_ms"
slo: "<200"
window: "5m"
- sli: "error_rate"
slo: "<0.2%"
verification:
- "压测脚本/混沌演练/契约测试"
runbook: "恢复步骤与联系人"
owner: "xx@org"
risks: "主要风险与缓解"
三、示例(每例给出 QAS 六要素 + SLI/SLO + 设计战术 + 验证 + 监控/告警 + 运维要点)
示例 A:可用性(故障恢复)
-
QAS 六要素 -
刺激源:监控系统/健康探针或外部依赖异常 -
刺激:主服务探测到节点失败或链路中断 -
环境:生产环境 / 高峰或平峰均适用(均需定义) -
制品:核心 API Gateway + 支付服务链路 -
响应:在检测到故障后系统应自动切换到备用路径或备用区域,并通知值班工程师 -
响应度量:切换完成时间 ≤ 30s;总业务中断时间(MTTR) ≤ 5min -
SLI/SLO:SLI=”从故障检测到业务恢复的时间”;SLO= ≤ 5 分钟(99%)。 -
设计战术:多活/冷热备、健康探针 + 心跳、流量切换(DNS短TTL / 路由层面)、熔断与回退策略。 -
验证:定期故障演练(演练日志自动化),混沌工程每季度一次;CI 中包含流量切换演练脚本。 -
监控 & 告警:指标:health_failures、failover_time;告警:failover_time > 30s 且未自动恢复 → P0 通知(短信/电话)。 -
Runbook:自动回退步骤、紧急联系人、回放日志位置、回归验证点。 -
风险 & 缓解:DNS 缓存导致切换延迟 → 缓解:短 TTL + 路由层面优先。
示例 B:性能(延迟与吞吐)
-
QAS六要素:刺激源=外部用户请求;刺激=下单请求;环境=高峰(1万rps);制品=订单服务;响应=P95 < 200ms;响应度量=P95延迟、吞吐≥1000 req/s。 -
SLI/SLO:P95_latency_ms < 200ms(5m 窗口);吞吐 SLO≥1000 rps(1m 窗口)。 -
战术:多级缓存、异步写入、优先队列、后端批处理、连接池、热点隔离。 -
验证:容量测试脚本(逐步加压到目标 + 超载场景)、长稳(24h)测试。 -
监控:延迟直方图、P95/P99 曲线、队列深度、后端依赖延迟。告警:P95 超阈 3 次采样窗口。 -
运维:当 P95 超阈且队列增长,触发自动扩容或速率限制降级,并记录错误预算消耗。
示例 C:安全性(非法访问)
-
QAS六要素:刺激源=未授权主体/异常IP;刺激=尝试访问敏感接口;环境=线上;制品=用户数据服务;响应=3s 内阻断并记录审计;响应度量=阻断时间 ≤ 3s、审计记录完整率=100%。 -
SLI/SLO:attack_detection_time < 3s;audit_log_written = 100%(写入并持久化)。 -
战术:WAF/IDS、速率限制、mTLS、RBAC/ABAC、审计流水线、不可篡改日志(WORM)。 -
验证:渗透测试、红蓝对抗、合规审计。 -
监控:安全事件数量、检测时间分布、未授权请求比率。告警:检测到异常行为并未在 3s 内被自动阻断 → P0。 -
Runbook:取证流程、隔离受影响节点、通知法务/合规。
示例 D:可修改性(一天改法)
-
QAS六要素:刺激源=产品需求变更;刺激=新增优惠策略;环境=开发/预发布;制品=优惠服务与相关 API;响应=在 1 个工作日内完成修改与回归验证,不影响线上用户;响应度量=开发工时 ≤ 8h、影响模块 ≤ 3、回归用例 100% 通过。 -
SLI/SLO:change_lead_time <= 1 day(小改);回归失败率 = 0。 -
战术:接口向后兼容、特性开关、灰度发布、契约测试与自动回归、模块化代码、良好边界。 -
验证:本地单元 + 集成 + 契约测试 + 小规模灰度验证(10% 流量)后放全量。 -
监控:回归失败计数、灰度阶段错误率。告警:灰度阶段错误率上升 > 阈值 → 自动回滚。 -
治理:对”1天改法”定义清单(不含数据库大变更、长时间迁移等),并在 ADR 中记录。
示例 E:易用性(新用户上手)
-
QAS六要素:刺激源=新用户;刺激=首次使用主流程;环境=标准教育材料/引导打开;制品=Web App 主流程;响应=30 分钟内掌握核心操作并执行成功,错误率 <5%;响应度量=任务完成率、首次成功率、平均完成时间 <30min。 -
SLI/SLO:first_time_success_rate >= 95%;avg_completion_time <= 30min。 -
战术:逐步引导(onboarding)、示例数据、内嵌帮助、撤销/确认、冗余提示、一致性 UI。 -
验证:可用性测试(用户测试样本)、A/B 测试、遥测(用户行为漏斗)。 -
监控:任务流中断率、用户行为漏斗转化、用户反馈(NPS)。告警:关键路径转化 < 90% → UX 投入评估。 -
改进循环:每月做一次可用性回顾并迭代引导流程。
四、把 QAS 与工程闭环连接(SLO → 验证 → CI/CD → 监控)
1.每个 QAS 映射到 1-2 个 SLI(可观察的度量),并定义 SLO(目标值 + 时间窗口)与错误预算。
2.在 CI/CD 中引入契约测试/集成测试/性能烟雾,对高优先 QAS 把失败设为门禁(阻断合并/发布)。
3.将 SLI 数据接入监控平台(Prometheus/Datadog 等),在 MTL(分钟/小时/天)级别计算 SLO,配置错误预算告警。
4.定期(如每两周)用 ATAM 小型会话复盘”敏感点/权衡点/风险主题”。必要时用 CBAM 估算进一步投入的 ROI。
5.每个 QAS 需有 Runbook 与演练计划(演练结果入档,定期复测)。
五、QAS 撰写与评审清单(快速校验)
-
刺激、环境、制品是否明确? -
响应是否描述系统行为而非实现? -
响应度量是否具体(数值/分位/窗口)? -
是否写了对应的 SLI 与 SLO? -
是否指定了验证手段(压测/混沌/契约/可用性测试)? -
是否有 Owner、Runbook 与告警策略? -
风险与缓解是否列出?
夜雨聆风