如何写好一个技术方案对于开发来说非常关键,这是一个工程类技术方案模板,基于我之前的一些积累,适合相对独立的业务需求承接。
实际开发中可以作为一个模板来套用,在这个基础上进行增加或者删减。
一、概要
很多时候,大家做项目的时候容易陷入为了上线而上线,尤其技术出身的同学,接到一个项目后,会陷入快速了解需求、做方案的圈子里。
通过概要分析,先了解下你要做的项目、在整个业务发展过程中所处的位置及价值,可以简单问几个问题,相信会有所帮助:
1、项目是解决哪个业务的需求?处于什么发展阶段?
2、当前业务有哪些问题/优化空间/增长点,通过这个项目能否解决?
3、参与业务上下游有哪些角色?
4、项目的成本和收益如何评价,有没有可衡量的指标体系?
5、后期业务发展的趋势如何?未来可能的增长规模多大?
基于以上的问题,为后续落地的方案可扩展性及未来业务发展做预判。
1.1 术语
统一术语的目的是让沟通在一个频道上,避免出现鸡同鸭讲,在项目后期出现返工等现象。
把术语放在最开始,以确保本文档的阅读者能够在一篇文档中就可以了解所有的关键术语。
- 术语将贯穿需求、分析、设计、开发、测试、维护阶段,在整个项目的生命周期中,参与者都将以统一的术语交流。
- 术语定义要求精确,严格,且勿模糊,含蓄;
- 寻找术语的方法:从需求文档中寻找那些多次出现的名词,业务名词,系统分析时引入的抽象概念。
- 术语范围:产品名称相关的名词,业务相关的名词,参与者相关的角色名词,边界、额度、时间相关的名词,系统抽象的名词。
- 如果在PRD文档中已经定义了某一个术语,建议在此处引用定义。
示例:
优惠券:商品促销手段,通过发放或者领取两种渠道,让用户在下单时抵扣一定的金额。
1.2 背景
背景是STAR法则中情境(situation)的体现,一般来自需求提出者,产研等部门。
背景通常包括项目内外部、团队内外部、组织内外部、公司内外部等。
综合不同维度上的背景,可以综合反映项目当前的价值,帮助下一步统一项目目标。
1.3 目标
基于背景分析,明确项目的目标,项目开发的意义,挖掘用户真实的可评测目标。
1.3.1 商业目标
商业目标一般会在PRD文档中明确,列出商业目标的目的是为了让我们的系统分析不要偏离业务主线。
1.3.2 系统目标
系统目标是为了支持商业目标,是商业目标在系统层面的具体化。
系统目标只是达到商业目标的充分条件,当我们的系统最终达到这几个方面,也意味着系统完全能够支持商业目标,但商业目标能否实现,与系统目标没有必然关系。
- 系统目标应该是具体的,可以实现的,可以达到的,相比商业目标是可落地的。
- 对于技术型比较强的系统,一些技术上要达到的指标也是重要的系统目标。比如一些中间件产品的技术指标,RT,SLA等。
系统目标要从当前需求出发,不局限于当前需求。
系统分析不是简单的对PRD当前需求的满足,而是站在整体产品的角度来看本次需求处于产品的那个位置,该位置在产品中的目标就是一个具体的系统目标。
二、总体设计
2.1 业务主流程
“如果你不能用一个过程来描述你正在做的事情,你就不可能真正明白你在做什么。” —— By W.爱德华兹.戴明 (PDCA循环的推广者)
- 系统的业务流程与具体的一个用例的流程有哪些差异?
业务流程从系统全局来看,用例关注的是自己内部的流程。
系统的业务流程是用户要完成他的业务目的,在系统层面发生着什么样的流程、事件来支撑用户的业务。
此处的流程节点同时是粗粒度的,它关注数据流、事件流在系统里的流转。
- 对于一些内部系统,如CRM、OA等,系统业务流程可能会成为设计阶段的BPM流程的主要来源。
- 对于一些小的项目,可能不存在复杂的流程,它们只是简单的请求-处理模式,此时可以不去关注系统业务流程。
- 对于那些改造型的项目,如果没有流程的变化,可以沿用已有的用例。
- 如果发生了变化,要把2个版本都画出来,且对差异之处进行重点说明。同时差异之处也是我们系统分析的重点。
2.2 系统整体架构
- 根据从相似系统或相似问题领域中获取的经验,定义备选架构和模型。
- 可以结合一些成熟的外部实例,比如电商可以参考淘宝、京东类似业务的设计。
- 通常需要产品团队和技术同学一起迭代来确定架构和模型,可以分为业务和技术架构。
2.3 业务系统边界
通过梳理业务系统边界,明确系统的上下游关系。
示例:
2.4 关键技术及第三方框架依赖
本系统采用了哪些关键技术,如业务算法、分布式session、分布式事务、分布式cache、分库分表等。
本系统引入了哪些外部框架、jar包。
三、模块实现
3.1 整体模块设计
模块的划分,相关描述
3.2 模块间交互接口
对接口的输入,输出,主要作用,使用场景做描述,输入输出中传递的值对象,也要做描述。不需要描述接口的实现细节。
3.3 状态机设计
对于一些复杂状态的流转,建议通过状态机的方式来描述。
3.4 XX模块功能实现
3.4.1 模块描述
输入输出,功能描述,UC图等
示例,秒杀模块设计:
3.4.2 业务流程
几个图可根据情况选择,但至少要有一个。
例如:状态图,流程度,顺序图
3.4.3 改造点(可选)
如果是改造型功能,列出改造
3.4.4 算法设计(可选)
系统内用到的算法要有技术公式和计算步骤,参数管理方案等。算法要充分考虑性能因素,大批量操作的部分要首先保证性能。需要加密的数据要定义加解密方式。
3.4.5 核心业务逻辑类图(可选)
核心业务逻辑的实现方法可事先定义好,把类图画出来
3.4.6 接口设计详细说明
比如RPC接口,HTTP接口,可以通过单独的文档描述
3.5 YY模块实现设计
同 XX模块设计
3.6 基础模块设计
可以从以下几个角度进行分析:
- 项目中那些公共组件是很多业务通用的?
- 改造了那些公共组件是替他业务也在使用的,对其他业务有什么影响?
- 那些基础设施在本项目中设计,但是以后也打算给其它业务使用?
- 给其它业务使用过程中是否需要扩展,修改?
- 本项目中是否已经做了本项目用不到的超前设计?
- 超前设计是否需要评估和测试?
3.8 关联系统改造
描述关联上下游系统需要的改造。
四、数据存储设计
描述数据库的设计,包括新的设计和原来设计的修改。
4.1 领域模型设计
- 关注模型,设计ER图等描述数据库设计
示例,权限模型的ER图:
4.2 数据库设计
4.2.1 表结构设计
- 表中字段长度要留有余量,每个字段都要有详细说明
- 如果记录可能删除,建议用DELETED表示是否删除(0正常,-1删除)]
- 预估变化比较多的表,可以增加extend活着feature字段,用于将来可能增加的字段,以键值对形式追加
4.2.2 分库分表设计
- 影响分表选择的因素是表的业务是否支持水平拆分、表的大小、表的访问量(QPS+TPS)。
- 拆分的前提是表的业务有一个好的水平拆分维度。如买家id、商家id、订单id,都可以作为拆分的维度。、业务SQL,必须避免跨分表。
- 表大小上一定规模后,无论是根据pk查询还是根据二级索引查询,sql的rt都会随着表的大小增长而增长,最终超出应用对数据库响应时间的需求。所以,表大了要分表。
- 表的访问量上一定规模后,对于根据二级索引查询,sql的rt会随着page读写冲突概率的增加而增长,最终超出应用对数据库响应时间的需求。所以,表的访问量高了也要分表。
4.2.3 数据字典设计
- 数据字典中要定义状态值描述
4.2.4 索引设计
- 列出使用的主键索引,唯一索引,普通索引。
- 常用的组合查询条件等
4.2.5 优化设计
注:数据冗余,优化查询方案等
- 表之间的关系要简单,涉及到多表的复杂查询和跨数据库的操作要合理使用冗余字段。
- 数据删除一般要采用逻辑删除,逻辑删除的数据要有清理机制。
- 合理利用事务,误操作后数据如何恢复。
- 根据数据流量,执行频率,制定分页方案。
- 要考虑数据库的设计方案对存储成本有多少影响。
4.3 缓存方案设计
- 缓存选型,本地缓存设计,分布式缓存设计
- 进一步需要考虑缓存失效等常见问题
4.4 ES索引设计
列出可能需要的索引层设计。
五、数据安全和风控
5.1 业务和数据安全
业务安全可以从如下几个方面考虑:
- 外部系统提交的数据是完整的,能够满足我方进行数据核对的需求
- 我方返回的数据是完整的,能够满足外部系统进行数据核对的需求
- 业务数据的机密性,关键业务数据、敏感业务数据
- 传输过程中涉及到隐私和机密性,需要找出来,采取对应的措施予以解决
- 系统支持那些类型的外部访问者,对访问者进行标示,访问者标示和业务数据的关系限制
- 并发情况下,数据的安全性,主要体现在脏数据,错误数据方面
- 当存在与外部数据关联的情况下,如果关联失败后,数据不完整的处理方案
5.2 资损风险分析
只要涉及资金(如广告消耗)和电商履约(如商品出库)的项目,都存在资损风险。
5.2.1 风险列表描述
- 添加资损评估checklist内容。
- 本项目所有的资损风险点,在此处都要有分析描述。
5.2.2 资损防控方案分析
针对某些资损风险点,需要通过一个完整的方案才能从根源上解决资损风险,具体的方案分析在这里展开。
比如,在做电商退货退款的业务设计,我们要从几个角度进行防资损:
- 保证退款业务操作的唯一性,针对所有请求都遵循幂等性原则;
- 保证幂等检查的正确性,如果通过数据库进行幂等控制,要考虑业务重试的风险;
- 保证退款金额的合理性,退款金额不超出原有的支付金额,在系统模型的设计上要有所体现;
- 保证并发情况下,不会出现超额退款;
六、性能和可测性
6.1 容量规划
从系统目标和业务的角度,进行合理的容量规划。
6.2 性能分析
从业务的角度分析对性能的需求:
• 对事务的响应时间(平均、最长)
• 吞吐量(例如每秒处理的事务数)
• 容量(例如业务所能容纳的客户或事务数)
在性能分析的时候,通常关注业务链路的起点、连接点、受限制的资源点。
6.2.1 并发访问控制
至少可以从以下方面分析:
- 有没有资源需要并发访问控制?
- 有没有资源在并发控制出错的情况下会造成损失?
- 并发访问控制会不会造成性能瓶颈?
6.2.2 接口性能延时要求
- 有没有具体的指标或要求?
- 有没有可能影响现有系统?
避免使用统一的指标要求所有业务,可能各个系统use case,或各个业务有不同的性能要求,应该要分别描述。
6.3 可测性分析
可以从以下方面分析:
- 系统依赖的外部环境是否可以测试,是否需要开发专门的mock系统
- 系统依赖的时间因素是否可以测试,是否需要开发专门的配合工具进行测试
- 系统依赖的时间,环境,权限等因素是否可以预发布确认,是否需要特别的准备才可以预发布确认。
- 系统依赖的特殊因素如果不能很好的测试或预发布确认,是否需要试运行策略?
七、稳定性设计
7.1 系统降级方案
考虑极端场景下,系统的降级方案。
7.2 系统容错分析
系统的容错能力可以从以下方面进行分析:
一、系统所依赖的外部系统发生一些错误的时候,系统有没有相应的容错机制
二、系统所依赖的硬件网络等基础设施发生故障,系统有没有相应的容错机制
由于所选择的通信,存储等方面的不可确定的因素,以及在某一个临界点处导致的质变,需要我们在此处指出可能存在的风险以及解决方案。
- 通信层面常出故障:例如带宽太小
- 文件系统:文件系统损坏、文件系统容量、文件系统每个目录所能容纳的目录、文件数量的限制
- 文件系统同时打开的句柄数的限制,间接影响并发行、文件自身的损坏
7.3 系统和业务监控
可以从以下方面分析:
- 系统发布和运行期间是否需要系统日志做监控
- 系统发布和运行期间是否要对原有业务做监控,以便知道影响
- 有没有制定新的一些重要的监控指标
- 系统是否在特定情况下需要一些报警
- 系统有没有考虑以后方便的扩充监控
- 监控发现严重问题是否有方法来得及挽回损失
7.4 系统日志
可以从以下方面分析:
- 日志的写入量有没有明显变化,异步或者同步,会不会影响业务
- 是否有新的需要长期归档的日志,请遵守命名规范
- 那些业务需要从日志中进行分析,以方便进行监控或排错
- 作为外部交互凭据的日志是否有归档,并和其它日志分开
八、数据影响分析
8.1 对已有业务数据分析的影响
可以从以下方面分析:
- 本项目所作的改造有没有影响现有的数据分析进行
- 本项目所作的改造有没有影响现有的业务数据分析结果
- 如果不明确影响,应该主动找数据分析团队沟通
8.2 发布期间影响分析
可以从以下方面分析:
- 是否有兼容方案,可以做到业务无感知
- 系统发布期间服务是否正常可用
- 系统发布期间对用户有没有影响
- 系统发布期间新老系统共存产生的数据有没有影响
- 各个系统发布顺序有没有要求
- 系统发布期间的兼容性是否建议专门测试
8.3 数据归档方案
可以从以下方面分析:
- 新增的表是否需要回流到HIVE表进行存储
- 如果表的数量持续增长,是否需要进行数据归档,对历时数据进行定期清理
九、工作量评估
9.1 工作量评估
拆解到人天,可以划分具体里程碑。
十、发布计划
10.1 上线计划
根据具体的业务情况,选择是否需要灰度上线、AB方案等。
评论区