Skip to content

如何出一个技术方案 ​

定位:工程实践方法论。技术方案不是"把代码翻译成文档",而是在动手之前,用最低的成本把设计错误暴露出来。方案评审阶段改一行字,上线阶段可能就是一个故障。这篇整理出一份方案文档的骨架和每节要回答的问题。

骨架总览 ​

一份能过评审、能指导开发、能兜住风险的方案文档,固定七节:

1. 背景与目标      —— 为什么做,做到什么程度算成
2. 方案对比        —— 为什么选这个,而不是别的
3. 详细设计        —— 怎么做:流程、数据、接口、异常
4. 容量估算        —— 系统扛不扛得住,要花多少钱
5. 灰度与回滚      —— 怎么安全地上,出事怎么退
6. 风险清单        —— 哪里可能出问题,各自怎么兜底
7. 排期与里程碑    —— 谁在什么时间交付什么

前两节决定"该不该做、该这么做吗",中间三节决定"上线会不会翻车"。最后一节决定"什么时候能见到结果"。

一、背景与目标 ​

要回答的三个问题:

  • 业务背景:什么业务场景、什么具体困难、谁提的、多紧急。不要写"为了提升系统稳定性"这种空话,要写"大促期间订单查询 P99 超 3s,客服工单每天 +200"。
  • 现状与问题:当前方案的数据流/架构描述 + 量化的问题指标。画现状架构图,标注问题发生在哪一环。
  • 目标(可量化、可验收):
    • 好的目标:"查询 P99 从 3 s 降到不超过 300 ms,大促峰值 10 万 QPS 下可用性 99.99%"。
    • 坏的目标:"优化查询体验,提升系统性能"——无法验收,也就无法结项。
    • 同时写非目标(Non-Goals):明确本期不解决什么,防止范围蔓延,也防止评审时被带偏。

二、方案对比 ​

至少给出 2-3 个候选方案,包括"什么都不做"的基线。没有对比的方案,等于把选择权丢了。评审者不知道你为什么走这条路,也就无法判断这条路对不对。

对比维度 ​

维度说明
功能满足度是否覆盖全部需求目标,有无语义损失
性能与容量延迟、吞吐是否达标(引用容量估算数据)
复杂度开发量、依赖组件数、运维复杂度、团队熟悉度
可演进性下期需求来了要不要推翻重来
风险每个方案各自的失败模式
成本机器/云资源费用、人力排期

写法要点 ​

  • 每个方案给出一图(流程/架构图)一段话(核心机制),不必等篇幅展开,重点讲差异点。
  • 结论要明确:"选方案 B。放弃 A 的原因是 X(量化),放弃 C 的原因是 Y(量化)。"
  • 被否掉的方案留着别删——半年后有人再提同样的想法时,这份对比就是决策记录。

三、详细设计 ​

选定方案后展开,覆盖五个视角:

1)整体流程 ​

  • 核心链路的时序图/流程图:请求从哪进、经过什么、落到哪。
  • 同步链路与异步链路分开画;标注每个边界的协议(RPC/MQ/HTTP)。

2)数据设计 ​

  • 表结构变更(新表 DDL / 老表加字段)、索引设计。
  • 存量数据怎么办:要不要迁移、迁移方案、迁移期间新旧数据如何共存(详见兼容性篇)。
  • 数据生命周期:增长速度、归档/清理策略。

3)接口设计 ​

  • 对内对外接口的签名、语义、错误码。
  • 幂等性:重复请求的语义(尤其涉及写操作的接口)。
  • 限流与鉴权:接口级别的保护。

4)异常与降级 ​

  • 每个依赖故障时的行为:失败重试几次、超时多少、最终是返回错误还是降级。
  • 核心链路 vs 非核心链路划分:非核心可降级(开关一键关闭)。

5)监控与告警 ​

  • 上线看哪些指标(QPS/RT/错误率/资源水位),阈值多少告警给谁。
  • 方案里没有监控设计等于盲飞——出问题时你没有观测手段。

四、容量估算 ​

用数量级估算回答"扛不扛得住、要多少资源"。不需要精确,需要不差数量级。

估算套路 ​

1)拿到业务量假设:日订单量 / 用户量 / 峰值系数(大促按日常 10 倍估)。

2)推导每类资源需求:

QPS   = 日请求量 / 86400 × 峰值系数
存储  = 单条大小 × 日增量 × 保留天数 × 副本数 × 2(索引与膨胀)
内存  = 单请求峰值对象 × 并发数 + 缓存条目 × 单条大小
带宽  = 单请求平均报文 × QPS
连接  = QPS × 平均耗时(Little's Law:并发数 = QPS × RT)

3)对照资源上限,算出冗余度:低于 50% 冗余就需要扩容或优化。

常见坑 ​

  • 只算应用服务器不算 DB:QPS 上去了,先死的是数据库连接数和磁盘。
  • 只算均值不算峰值:压垮系统的是峰值,平均值只在报表里好看。
  • 忘了 MQ/缓存等中间件的容量:消息堆积一天的磁盘、Redis 的内存水位。
  • 忘了下游容量:自己扛住了,把下游打挂了,事故照样是自己的。

五、灰度与回滚 ​

发布策略 ​

  • 发布顺序:依赖方先行(先建表、先发下游、最后发入口)。
  • 灰度路径:白名单用户 → 1% → 5% → 20% → 50% → 100%,每档观察时长写明(如至少一个流量高峰周期)。
  • 每一档观察什么指标、什么阈值触发暂停,提前写死,避免现场拍脑袋。

回滚方案 ​

  • 回滚是设计出来的,不是"把代码 revert 就行":
    • 代码回滚:确认无不可逆变更(老代码能否读新格式的数据/消息)。
    • 数据回滚:迁移类变更要有反向脚本或快照;DDL 尽量兼容式(先加后删,删放最后一步)。
    • 配置回滚:开关默认值 = 安全值(老逻辑),出事关开关即回退。
  • 回滚演练:第一次灰度前把回滚动作走一遍(至少预发环境),确保回滚路径真的通。

六、风险清单 ​

逐条列出风险与对策,宁多勿漏。按影响 × 概率标级:

风险影响概率对策兜底
新缓存与 DB 不一致数据错误中延迟双删 + 过期时间对账任务校准
MQ 消费积压延迟上升低消费端扩容 + 告警降级读库
存量数据迁移超时窗口停机超时中分批迁移 + 断点续传回滚到旧链路

三个必答题(答不上来就不要上线):

1)这个变更最坏情况影响什么、影响多大范围? 2)出问题后多快能发现(监控/告警覆盖了吗)? 3)发现后多快能恢复(回滚动作用时多少)?

七、排期与里程碑 ​

  • 按交付物拆分(DDL / 接口 / 联调 / 灰度 / 全量),不要按"开发 5 天"这种黑盒拆。
  • 标出关键依赖路径与外部依赖方(需要别的团队配合的,提前锁定时间)。
  • 留 buffer:联调 + 灰度观察时间通常被低估。

评审要点 ​

评审会前发出文档(给评审者至少半天阅读时间),会上聚焦三类问题:

  • 目标层:这个目标值得做吗?目标达成的验收方式成立吗?
  • 方案层:对比是否充分?有没有更简单的做法?复杂度是不是过度设计?
  • 风险层:容量估算靠谱吗?回滚真的可行吗?风险清单有没有漏项?

会上达成的修改意见当场记录到文档修订记录。方案文档随实现过程持续更新——它应该是活文档,结项时的版本就是系统的真实模样。

一句话总结 ​

目标可量化、方案有对比、容量有账本、灰度有梯子、回滚有路、风险有清单。 六个"有"齐了,方案就立得住;缺任何一个,评审时被挑战的就会是那一节。

2026-10 依据主题重写(原文件为空壳)。