通常情况,技改方案要面对的问题其复杂度要比新应用和一般的功能优化要高。在保证业务发展不受影响的大前提下,即要结合历史现状解决痛点,又要着眼未来的整体规划和布局,还要尽量做到可以小步长的快速迭代,不断进行局部治理 。所以有价值、有规划是前提,稳定性、兼容性是基本要求,有时还要考虑做到可切换 、可灰度等上线和应急策略。 技改要做的好,技改文档和方案评审非常重要,而写技改方案文档,其关键有三点:
- 关键信息表达清楚;
- 控制合理范围;
- 关联性分析、安全性分析、测试分析等尽量的全面。
在下文中,我将之前若干次技改方案文档,涉及到必要内容进行了合并,形成一份较全面的技改方案模板,并简单介绍各个部分的作用和表达方式。PS: 并不是设计文档一定要面面俱到,从中参考必要的部分即可。
价值分析
价值分析是重中之重,立意不详,何谈方案。价值分析通常可以包括以下几点:
- 本方案改进内容,属于哪些规划中的那些部分或环节,在整体规划上的价值和作用(背景介绍)
- 解决哪里痛点问题,包括业务痛点、技术痛点(核心价值)
- 还有那些后续的迭代安排和规划、可能的发展方向以及可继续挖掘的价值(增值空间)
方言定义
为了方便理解,尤其是业务需求与技术实现之间建立有效的关联,需要对一些关键字进行定义和解释。
- 对一些核心模型进行定义和强调说明
- 对相关参与者定义进行明确说明
- 对于一些简称和专业术语进行解释
业务模型设计(领域设计)
业务模型设计分析,是以面对对象思想解构和转化业务需求的关键环节,建议以领域驱动的思想,对业务对象和活动,进行明确的领域划,并对领域之间的交互和依赖关系,进行相应的交互设计。并不要求完全搞懂DDD,但是SOA设计理念出发,面对对像设计思想,都是相通的。所以业务架构和应用架构层面的设计,都围绕领域模型的边界和关系展开,才更利于业务规划与技术规划协同以及架构和代码防腐。
几点小建议:
不管业务逻辑是否复杂,领域划分,业务模型颗粒度、层级划分都值得深思,发掘事务的本质;
如果业务逻辑比较简单,核心业务模型可以是简单的POJO 或 Entity(贫血模型),但注意尽量避免模型继承,尽量遵照【合成复用原则】,采用模型组合。
如果是业务逻辑比较复杂且多变的业务域,其核心业务对象模型,通常需要为业务流程以及活动提供更多的描述和记录支持,所以要避免【贫血】(当然也不建议过度充血),建议核心业务模型作用域能涵盖业务流程整个生命周期。核心业务模型可以由三类对象组成:业务实体对象(Entities)、状态对象(考虑使用状态模式对状态对象进行扩展)、值对象(value)。
关键枚举和状态机 (模型生命周期管理)
软件系统通常都会创建一些状态类的枚举,这部分建议以表格形式,将状态和枚举项罗列清楚。
如果业务状态较负责,可以加上UML状态机图,来描述业务模型的状态迁移过程。
用户用例设计(用例图)
如果技改方案涉及【人机交互】部分,需要进行一定的UI交互设计,此时需要先明确【参与者】,这块需要注意的是,通常除了需求描述的直接参与者,还有一些间接参与者。
例如用户个人信息管理,直接参与者是【用户】,关联参与者可能是【运维人员】,可能需要代理用户进行处理,或后台协助用户处理(个人建议所有的前台场景,都要考虑下中后台配套的操作场景设计)。
如果PRD文档已经描述了用户用例图,此处的可以省略。如果技术驱动而不是需求驱动,则最好进行描述,方便和业务方确认。
业务流程设计(活动图)
业务流程设计由两种表达方式,一种是应用流程图,一种是活动图。说说两者的区别: 应用流程图,是从程序执行的过程角度,主要表达执行的步骤和过程。偏技术实现的视角,适合与技术团队沟通。活动图,更适合以业务设定的执行步骤进行表达,表达内容往往更贴合需求描述,适合技术与产品或业务人员沟通。所以这部分推荐以活动图的形式来描述,且尽量去除技术语言和应用模块的定义,仅以step by step的方式描述做什么,这个可以参考可视化工作流模板。根据个人经验,研发人员通过构建活动图,对业务理解和抽象非常有帮助。
研发设计
系统交互设计
微服务体系而言,系统交互设计应该以【应用】为最小粒度,通过关系图的方式来表达【应用】与【应用】之间的关系。 需要重点突出当前应用处于平台或关键体系中所处的位置。当然如果当前技改涉及的范围比较小,粒度也可以适当下降到应用模块的级别来表达交互关系。
应用架构设计
要表达你的应用架构设计,推荐以应用内业务模块、功能组件模块为基本单元,以分层结构图的方式,表达出应用内部的技术架构,例如Facade层有哪些对外服务的功能模块,业务层有哪些业务功能模块,内部领域核心有哪些领域标准服务模块,持久层功能模块等。
通常,应用架构设计,对应着一个软件工程的分层、分包、甚至是maven 模块划分的方式。需要注意的是,模块的粒度,不要太细。可以最小要对应到java package级别。
关键流程时序
关键流程时序图,是技改方案最直接、最容易理解的表达方式。 对应上文的 系统交互设计进行一下说明:
系统交互设计,可以仅表达系统之间存在关联,用于提现系统集成情况;
关键流程时序,必要时也提现系统之间的交互,而且提现调用链路,执行顺序等详细信息,面向实际开发实现细节。 所以个人建议,一定要把时序图画清楚。另外需要注意的是,时序图的各个item,颗粒度要一致,如果是系统级别,就要都是系统,如果是模块就都要是模块,切忌不要混用,容易造成误会。
存储结构设计
存储结构设计,要考虑存储介质选型和模型设计。
- 存储介质选型,基于不同的业务特性,选择一种或两种存储介质,如Mysql、Mongodb、ElasticSearch、CouchDB以及缓存Redis 、memcache 等。
- 数据模型设计,关系型数据库有的数据模型以及关系设计,非关系型数据库的文档模型对象设计,根据业务需求来定。
兼容性设计
兼容性设计,主要考虑两个方面,与其他系统交互的兼容性,历史数据的兼容性。
- 交互兼容性: 如果服务接口有较大变化,依赖方又不能同步改造,就需要做好接口兼容策略。
- 数据兼容性:历史数据需要处理,还是新旧数据模型同事存在,逐步同步融合,也需要做好相关的上线前、上线中、上线后相关处理方案的设计。
分布式风险
方案中涉及的逻辑或业务数据,在分布式场景下,需要慎重考虑,是否要分布式锁和最终一致性高保障,尤其是如果存在高并发的情况,更要做好性能和一致性的平衡策略。
幂等设计
幂等性设计,要求服务接口的调用请求,允许被重复执行,尤其是微服务架构下,业务链路较长时,中间服务如果存在重试或补偿机制,用于处理局部失败,链路下游服务几口如果不具备幂等性,业务数据存在被污染的风险,所以幂等性设计是非常有必要。
依赖设计
依赖设计分为依赖系统和依赖接口
依赖接口,主要考虑交互频次、交互时机、交互数据包大小、属性映射关系、数据类型转换、失败处理、超时熔断等问题
依赖系统,主要考虑多接口依赖场景下,对下游的访问压力问题
测试分析
单元测试用例
如果时间允许,强烈建议开发人员做好单元测试分析,设计好单元测试用例。
从项目之处就累计单元测试,方可形成持续高质量交付。
接口测试用例
对于微服务而言,通常通过接口测试,来保证当前服务的质量;而接口测试分析,也是对当前服务能力的全方位理解和检查。更是持续交付持续集成高效率的有效保障
很多日常维护工作效率高不高,就看接口用例全不全
场景集成用例
关联回归用例
在单元测试、接口测试已经有一定积累的情况下,还需要列好回归范围,和包含的回归用例清单。
风险评估
风险评估是最考验业务掌控程度和服务实现水平的环节。
众所周知一个腐败的平台或应用,一些小改动都可能带来很大的风险。
遗憾的是,日常工作中不得不面对这样的改造任务,所以风险评估需要慎重对待。