一份好的文档可以在未来替你向别人回答类似下面这些问题:
对于整个团队,通过技术方案文档和评审对齐,可以提高沟通效率:
很多祖传项目都是没有文档或者文档只是画了几张架构图和寥寥几句话的,既没有给出每个需求的背景,也没有讲解业务逻辑和架构设计思路,代码注释也非常少。接手者只能强行阅读代码,推测每个变量的含义,一点点梳理业务逻辑,跟抱着一本厚书硬啃一样。
对于开发同学,通过写技术方案,可以提高开发效率和质量:
在说如何编写一个好的技术方案之前,先说说一个错误的方案是什么样的。
错误方案 | 正确方案 |
---|---|
没有思考清楚模块的职责、关系、边界(约束和指导原则) a. 模块职责混乱(比如本该负责鉴权和数据交换的cgi层写了复杂的计算和IO任务代码) b. 模块关系混乱(比如用户服务中调用了订单服务用来显示用户买了什么订单,而订单服务又调用了用户服务显示订单中的收获地址,最好将双向依赖改为单向依赖,参考软件系统解耦:理解依赖关系) c.边界混乱(用户服务中写了订单服务的代码,订单服务中写了用户服务的代码) |
明确模块的职责、关系、边界 |
技术方案和技术选型没有纵向对比和横向对比 a.没有对以往的业务逻辑进行review,修改的代码导致以往的业务无法兼容,出现不可预知的bug b.没有对技术选型进行业内调研和对比,用到的基础技术在某个环节无法支撑你的变更,只能重新选型。比如不建议在核心项目中使用不确定性高的新技术,否则容易踩坑。 |
技术方案和技术选型要进行纵向对比和横向对比 |
没有存储设计,或者给出的存储结构描述不够详细。 a.没有详细对齐每个字段的类型及其内部结构(比如一个string类型的uid列表,配置端认为[“111”,“222”],播放端认为是[111,222],导致播放端解析错误) |
给出存储设计,给出详细的存储结构,对齐所有存储(ES、MySQL、Redis、文件系统、CDN等等) |
没有容量预估和流量预估 a.服务请求量增大,挤垮服务器的cpu和内存 b.ugc数据太多了,数据库很快就被打满了,没有分库分表方案 |
给出流量预估和容量预估,预估存储占用大小(内存、持久化)、接口高峰期流量、MQ高峰期流量等 |
没有灰度方案。 在某种场景QA没有覆盖到,线上用户操作突然触发了,导致大量数据错误 |
给出灰度方案,灰度能够控制异常影响范围最低,出现异常时修复数据也最少 |
没有降级方案。 服务降级是服务自我保护的一种方式,一个服务的硬件资源是有限的,在流量激增的情况下,如果不能通过降级方案来拒绝多余的请求,会导致服务因为处理不过来而崩溃。 |
给出降级方案(自动降级、人工降级),要考虑降级是否对主流程产生影响,对数据是否产生影响,区分有损降级和无损降级,有损降级需要考虑后续数据修复的方案。(参考为什么需要服务降级以及常见的几种降级方式) |
没有异常处理方案 即使经过了QA测试,实际生产情况也总会出现异常情况,比如 a. 网络抖动数据写入失败,业务请求的数据丢失,要赔偿用户的损失 b. 用户违法输入,产生了sql注入 c. 中间件或存储崩溃,业务中断 d. 依赖服务挂掉,业务中断 |
考虑所有可能出现的异常情况,给出异常处理方案。 a.对于抖动、依赖服务短时间崩溃要考虑重试机制。 b.读流程是否可降级为不展示,写流程是否可有备选通道支持(比如MQ和接口双通道) c.对核心链路的异常要有告警机制。 |
总共七个点,后面四个点都是在考虑各种异常情况下的各种补救措施,所以一个好的技术方案设计需要考虑到尽可能多的异常情况。
墨菲定理:凡事只要有可能出错,那就一定会出错。
开发工程师需要对自己所接手的需求有清晰的认识,这包括:
格式如下:
一、需求说明
1、需求背景:因为xxxx,所以我们要xxxx,从而达到xxxxxxx的效果
TAPD链接:https...
2、相关人员:
产品:xxx
形态组前端:xxx
形态组后端:xxx
效能组前端:xxx
效能组后端:xxx
引擎组:xxx
天秤系统:xxx
测试:xxx
把这些内容写在技术方案的开头,有利于其他看技术方案的人快速理解需求,后面如果遇到问题也可以立马精准地找到相应的人。
思路不清晰的技术方案有一个常见的问题:在交代完需求背景之后,就直接开始介绍每个子需求的具体实现。这种技术方案各个部分比较分散细碎,没有统一成整体,阅读起来并不好把握,这些设计背后的思路是什么,为什么要这样设计。所以需要高屋建瓴,先概要地介绍系统的整体构成,以及每个部分的职责,后面章节再细节介绍每个部分的具体实现。
概要设计主要包括总体设计和模块设计两个部分。
说明系统总体上的架构设计,画系统架构图是介绍清楚系统架构的有效手段,架构图常见的归类有:
注意画之前要想清楚这张图要表达什么内容,再针对性来画,不同的类型的图不要合在一起。例如想说明系统的部署结构,用部署图,说明业务的主要流程,用流程图等。
简要说明每个模块的职责,或者说每个模块在本次需求中需要作出的修改。
详细设计可分成开发约定,功能实现,可靠性设计三个部分。
开发约定部分常见介绍的内容如下:
软件系统工作的核心功能是对数据的处理。因此具体功能实现部分重点关注的是数据链路,数据链路包括:
具体来说,常见的功能实现需要讲解这些内容:
我们不仅要考虑如何高效地实现系统功能,而且要尽量保证系统的稳定可靠。可靠性设计包括容量预估、灰度方案、降级方案、异常处理和监控告警。
容量评估需要根据请求量,评估要预留给程序多少相应的运行资源。包括内存,磁盘,CPU,存储服务等。
流量预估
流量来源一般包括对外接口和消息队列两种,用表格的形式给出
这一部分如果是改动的业务,可以参考以前的监控,如果是新业务则需要拉运营、产品确定业务量。若预估峰值会很高,则需要进行压测。表格例子:
模块 | 接口/MQ Topic | 报文大小 | 上线一周 | 上线一个月 | 上线半年 | 上线一年 |
---|---|---|---|---|---|---|
流量评估主要是看机器的CPU和内存能否扛得住业务请求量,
如果新增的业务逻辑所需的计算量和内存占用比较大,则需要进行功能实现的优化或者申请更多的机器资源。
数据量预估
用表格形式给出用到的所有存储在一段时间的数据量增长:
模块 | 表/索引 | 上线一周 | 上线一个月 | 上线半年 | 上线一年 |
---|---|---|---|---|---|
评估数据量增长后,存储系统是否能承受住压力,会不会存储空间被打满或者查询速度变慢,以及如何进行存储设计的优化。
灰度可以控制在出现bug的情况下的损失,一边灰度一边观察监控,有问题则及时回退。
用表格给出灰度范围、配置灰度开关的参数、灰度周期。例子:
模块 | 灰度维度 | 配置变更 | 灰度周期(1) | 灰度周期(2) | 灰度周期(3) |
---|---|---|---|---|---|
请求流量 | 第一周:20%流量,比如某些二三线城市 | 第二周:50%流量,比如一些一线城市+二线城市 | 第三周:100%流量,比如全国 |
即使通过灰度跑了很长时间,直到最后全量也没有出现问题,也不能100%保证这次代码改动是没有问题的。通常一个业务刚上线很稳定,但是随着时间的推移问题逐渐暴露,原因可能有很多:
所以降级方案是必须要有的,防止出现问题之后没有退路。所以说灰度是一个短期的及时止损方案,降级方案是一个长期的及时止损方案。
降级方案用表格给出业务模块或接口、降级方式(自动、手动)、降级是否对主要业务流程有损失、若有损失则要有对应的修复方案。在设计降级方案时,需要与产品、测试、业务人员进行充分沟通,说明降级方案,一起讨论可行性。
模块 | 主流程 | 是否可降级 | 降级流程 | 是否有损(对主流程) | 备注 |
---|---|---|---|---|---|
没有人能考虑到所有异常,但是只要考虑到尽量多的异常情况并且给出对应的异常处理方案,总会让业务更可靠一点。
每种异常情况需要列出这些内容:
模块 | 异常情景 | 处理流程 | 降级方案 | 损失与数据恢复 |
---|---|---|---|---|
监控告警可以帮助我们及时地发现问题,给出核心的业务指标和非业务指标(QPS、响应耗时、消息积压数等),关键指标出现异常(低于或高于某个阈值)要进行报警。表格形式说明信息:模块,监控指标,监控阈值,报警方式等。例子:
模块 | idkey | 指标 | 阈值 | 报警形式 |
---|---|---|---|---|
良好的测试方案能有效提高开发质量,技术方案中不仅需要考虑开发自测,为了进一步提高研发质量,还需要考虑如何提高测试同学的测试质量和效率。测试方案需要考虑的点包括:影响点,自测用例,测试注意点。
影响点可以用清单的形式列出本次开发影响了哪块功能,哪些接口,接口url,改动的内容是什么。这样测试同学在设计测试用例时可以做对照参考,减少功能遗漏测试的情况。
自测用例是介绍说明需求自测的用例设计,一般包括涉及场景,测试步骤,测试输入,期望输出等信息。
有些隐藏的异常情况处理,边界条件,特殊处理逻辑,如果没有特别说明,测试同学测试的时候很容易遗漏这块,而线上bug往往出现在这一块。
事先规划好上线部署的详细步骤,等到正式上线时就可以对着步骤来一步地执行和检查,减少上线事项遗漏或者处理出错的情况。
上线部署部分包括环境准备,系统准备,发布顺序,线上验证
系统依赖环境的准备包括MySQL、Redis、MQ、ES和Nginx等服务搭建和初始化,机器资源等。
系统准备常见主要如下:
如果不同的服务之间有依赖关系,在技术方案中应当标明。发布上线的服务依赖其他服务的情况下,需要先发布被依赖的服务。
线上验证的部分,需要说明服务发布上线之后,怎么验证服务是否正常,需要做哪些检查验证项。例如
参考文章:
如何写好技术方案
如何写一篇可实施的技术方案?
设计方案,写了才知道有多香