Appearance
技术架构:从业务损失推导容量、可靠性与运行机制
大促预计每秒 2500 次下单请求。有人提议把订单服务扩容到 2500 QPS,再把 Redis、Kafka 和 Kubernetes 加进方案。这个答案没有说明商品浏览、库存预占、支付回调、履约创建和短信通知分别承受什么流量,也没有说明一个依赖故障时交易应该暂停、排队还是降级。
技术架构不是产品清单,而是把业务场景转译成质量属性、运行机制和可验证的假设。它要解释系统如何承受压力、如何失败、如何恢复、如何被观测,以及这些能力的成本是否可接受。
先写质量属性场景
“高可用”“高性能”“安全可靠”都不能直接指导设计。质量属性场景至少包含主体、触发条件、系统响应和度量方式。
| 业务场景 | 触发条件 | 系统响应 | 度量 |
|---|---|---|---|
| 创建订单 | 大促峰值、热点商品集中 | 保护入口,完成必要校验,不超额承诺 | 成功率、时延、拒绝率 |
| 预占库存 | 同一 SKU 并发下单 | 对同一库存单元做原子裁决,重复请求返回一致结果 | 超卖率、冲突率、锁定超时 |
| 支付回调 | 重复、延迟、乱序或批量到达 | 幂等处理,状态不能逆向跳转 | 重复回调处理率、挂起量 |
| 消息积压 | 下游短时不可用 | 有界排队、告警、重试和死信,不拖垮交易 | 积压时间、重试次数、丢弃量 |
| 区域故障 | 单个机房或依赖不可用 | 按业务优先级降级或切换,保留审计 | RTO、恢复成功率、业务损失 |
| 敏感数据访问 | 管理员批量导出客户数据 | 强认证、最小权限、审批和审计 | 未授权访问、审计覆盖率 |
质量属性的价值在于它能让业务、应用和技术团队讨论同一个可验证场景,而不是各自使用“稳定”“弹性”这样的形容词。
容量模型从业务路径开始
同一个 2500 QPS 不能平均分配给所有服务。需要先拆业务路径和放大关系:
text
商品浏览 25,000 req/s
-> 商品详情读模型、缓存、搜索
下单入口 2,500 req/s
-> 订单创建 2,500 tx/s
-> 库存预占 2,500 tx/s
-> 支付意图 2,500 tx/s
支付回调 2,000 event/s(峰值可能滞后)
-> 订单状态更新
-> 库存确认
-> 履约创建
每个订单平均 3 个商品行、1.4 个履约单
-> 写放大、消息量和数据库索引压力不能按入口 QPS 估算容量模型至少保留这些假设:峰值持续时间、请求分布、读写比例、缓存命中率、单请求写放大、消息大小、数据库事务范围、下游处理速率和可接受积压时间。压测结果如果不回填这些假设,只能说明某次环境下跑过,而不能说明生产容量成立。
不同流量使用不同保护机制
| 流量类型 | 主要风险 | 合适的保护 |
|---|---|---|
| 商品浏览 | 热点、缓存击穿、搜索突发 | CDN、缓存、热点隔离、限流 |
| 订单创建 | 资源耗尽、重复提交、写入放大 | 用户/接口限流、幂等键、队列边界 |
| 库存预占 | 超卖、锁竞争、状态冲突 | 单一写入责任、原子操作、分区或串行化 |
| 支付回调 | 重复、乱序、下游不可用 | 状态机、幂等、持久化重试、人工挂起 |
| 履约通知 | 短时积压、第三方失败 | 异步队列、重试、死信、供应商切换 |
| 报表分析 | 大查询拖慢交易库 | CDC、数仓、查询隔离和资源配额 |
限流不是万能保护。对库存预占限流只能降低并发,不能决定两个请求中谁得到最后一件商品;对分析查询隔离资源比简单拒绝更重要;对支付回调丢弃请求会造成财务和订单状态不一致。
可靠性来自故障语义
设计“高可用”前,先明确故障时业务允许什么结果:
- 商品详情可以返回短时旧数据。
- 库存展示可以保守地显示不可售,但不能显示可售后再超卖。
- 订单创建在库存平台不可用时可以进入待处理,但必须给客户可查询的状态。
- 支付结果不能因通知失败而丢失,必须持久化并可重放。
- 积分、短信和营销触达可以延迟,不应阻塞核心交易。
这些选择会决定超时、重试、熔断、降级、队列和本地持久化的组合。重试没有幂等保护会放大故障,超时没有边界会占满线程池,熔断没有恢复策略会把临时故障变成长时间不可用。
RPO 与 RTO 必须对应业务状态
订单、支付和库存不能只共享一个“系统 RPO”。需要分别讨论:
| 对象 | 允许丢失什么 | 恢复优先级 |
|---|---|---|
| 已支付订单 | 不允许丢失支付事实和审计凭证 | 最高,先恢复写入和查询 |
| 库存预占 | 不能产生重复承诺,允许通过事件重放恢复 | 高,先恢复权威状态和对账 |
| 商品搜索索引 | 可从商品权威数据重建 | 中,交易可先降级查询 |
| 营销触达 | 可延迟或重试 | 低,不阻塞交易 |
恢复顺序也是应用和数据架构的决策。数据库备份成功不等于业务能够恢复,必须演练从凭证、事件、状态和读模型重建运行链路。
安全架构是数据与操作边界
技术架构中的安全不只是 WAF 和加密。全渠道系统至少要划分:
- 客户、门店员工、运营、客服、财务、平台运维和外部供应商的身份。
- 查询、修改、审批、导出和回放事件等操作权限。
- 客户数据、支付数据、库存策略和审计记录的敏感等级。
- 服务间身份、密钥轮换、短期凭证和调用范围。
- 管理员高风险操作的双人审批、理由和审计。
- 测试和分析环境的脱敏与数据最小化。
零信任不是把所有调用都放进认证网关,而是让每个主体、动作、资源和上下文都能被验证,并且权限随着业务责任变化。
平台能力要服务业务差异
平台工程应提供可复用的护栏,而不是把所有业务强行做成同一种运行方式。
| 平台能力 | 应提供的底线 | 不能替代的业务决策 |
|---|---|---|
| 发布平台 | 灰度、回滚、审计、配置分离 | 哪些变更可灰度,回退后数据如何处理 |
| 消息平台 | Schema、重试、死信、积压监控 | 事件语义、顺序和补偿责任 |
| 可观测性平台 | 日志、指标、追踪、关联 ID | 哪些业务状态代表成功或风险 |
| 身份平台 | 认证、授权、密钥和租户隔离 | 角色、业务权限和审批边界 |
| 数据平台 | 采集、血缘、质量和查询隔离 | 数据 Owner、口径和使用目的 |
| 容灾平台 | 备份、复制、恢复和演练工具 | 业务恢复顺序和可接受损失 |
平台能力只有被嵌入项目模板、流水线和运行手册,才会从“有服务”变成“降低交付风险”。
可观测性要从技术指标走到业务状态
CPU、内存和接口时延只能说明组件表现。交易系统还需要观察:
text
customer_id
-> order_id
-> reservation_id
-> payment_id
-> fulfillment_id
-> package_id围绕这些业务主键,可以回答:订单为什么停在待支付,支付成功后库存是否确认,锁定是否超时,履约单是否生成,哪一段依赖造成客户看不到状态。
建议把指标分成三层:
- 技术指标:CPU、内存、连接池、线程池、队列积压。
- 服务指标:请求成功率、时延、错误码、重试和降级。
- 业务指标:订单成功率、超卖率、支付挂起量、库存差异、履约及时率。
只看第一层,系统可能很健康而业务已经失败;只看第三层,又无法定位故障组件。三层需要通过追踪 ID 和业务主键连接。
成本是技术架构的约束
弹性设计需要说明在什么时段、为哪个业务结果支付成本。应当核算:
- 峰值容量的闲置成本和临时扩容成本。
- 多副本、跨故障域和备份带来的存储与网络成本。
- 消息重试、日志保留、链路采样和数据复制成本。
- 多套旧系统共存期间的双重运维成本。
- 为低价值、低峰值能力提供高等级可用性的机会成本。
FinOps 不是事后削减资源,而是把业务价值、质量属性和技术成本放在同一个决策记录中。为了省成本降低库存对账频率,可能把节省转化为更高的缺货和人工成本。
技术架构的最小交付物
- 业务场景、流量分类和容量假设。
- 可用性、性能、安全、恢复和成本目标。
- 技术机制与质量属性的对应关系。
- 关键依赖、故障域、降级和恢复顺序。
- 身份、密钥、数据访问和审计边界。
- 技术指标、服务指标和业务指标的关联。
- 压测、故障注入、恢复演练和成本验证结果。
- 平台能力目录、标准和例外清单。
常见失效方式
- 先选中间件,再寻找可以解释它的业务需求。
- 所有流量都按平均 QPS 估算,忽略写放大和峰值滞后。
- 重试、超时和熔断各自配置,没有统一的故障语义。
- 把数据库备份当成业务恢复,没有演练状态和事件重建。
- 只监控资源,不监控订单、库存和履约业务状态。
- 把平台标准当成业务架构,所有系统被迫使用相同模型。
- 只看单次压测峰值,不保留模型假设和持续时间。
能力验证
- 能把业务场景写成包含触发、响应和度量的质量属性场景。
- 能拆分流量类型、写放大、峰值持续时间和下游速率。
- 能为依赖故障定义暂停、排队、降级、补偿和恢复语义。
- 能把 RPO、RTO 和恢复顺序对应到业务事实。
- 能用业务主键连接技术、服务和业务观测。
- 能在性能、安全、可靠性和成本之间说明取舍。
总结
技术架构的核心是可验证的运行假设。它把业务损失转成质量属性,把质量属性转成容量、隔离、恢复和安全机制,再用压测、演练、指标和成本反馈校准方案。工具只是机制的实现方式;没有业务场景和失败语义,技术栈越丰富,架构越难解释。
