业务实践系列(3):项目重构思路
重构了一个项目,项目相对复杂,对外提供了很多接口产品给第三方调用,也调用多个第三方的数据,数据结构各种格式都有,业务有用户、登录、产品、订单、预付费/扣费、报表、客户、财务、对账等十多项服务。由单一架构拆分成多个Spring Boot微服务,Spring Cloud做服务管理。
重构后的项目也许在架构上仍存在缺陷,但比之前的单一架构则有较大的改进,非常方便横向扩展,大大降低了业务系统之间的耦合。本篇记录下重构的思路。
重构的目的主要是解决问题,如果问题不存在则重构没有意义,如果重构没有解决问题那更没有意义还浪费资源带来不可预知的风险,主要问题有:
- 架构开发效率低,业务高耦合,难以扩展,不适合现在的业务体系。
- 系统功能和性能遇到了瓶颈,难以支撑高速扩展的业务。
- 代码不规范,难以理清逻辑,改动风险大,代价高。
重构也是一种优化,只是该优化到了需要伤筋动骨的程度。重构事件大多是研发内部讨论判断得出的结果,由研发内部驱动,外部的产品、业务、测试等并不容易理解,重构需要的时间成本往往与完成新需求时间存在重叠,还带来了新架构的系统测试成本、回归测试成本、新技术学习成本、数据迁移成本等等。所以当做出需要重构结论时,一定要说予高层理解,阐明利弊,得到理解和资源上的支持,否则在 KPI 压力下会是件吃力不讨好的事。
前期准备
重构之前,做了大量的前期准备工作,收集已有的重构思路和方式方法,站在前人填过坑的路上走的稳健些, 见文未参考。
梳理业务
梳理并理解业务是重构项目的前提条件,保持对项目代码的敬畏,理解业务之前不要试着执行任何的重构操作。
因项目经过了好几批人的开发,持续的时间也比较长,中间缺少各种文档和流程图,业务逻辑无法直观通过文件了解。
- 让业务和产品讲解产品的具体功能。
- 开发根据功能进行粗粒度的模块划分。
- 阅读模块代码整理出业务逻辑和执行流程文档。
模块拆分
对模块进行拆分是重点也是难点,有的功能所属的范围域不太好界定,如果拆分重组不合理,就达不到重要构的目的。
- 根据业务功能和范围对原来的项目进行拆份,将原来项目划分两大块,分别是基础服务和业务服务,业务服务又分了两类,分别是消费服务和提供服务,共拆份成了 12 个微服务系统。
消费服务是自己做为消费方,向接第三方的数据接口发请求获取数据,将获取的原始数据统一解析成JSON格式;提供服务方是给客户提供数据产品, 在提供服务前面有一个抽象层,对原始的JSON数据进行了公司标准化的封装,在服务系统对外提供产品的业务继承抽象层做定制化的封装。 - 产品属于预付消费,基于产品属性和商务层面允许一次欠费, 订单系统与扣费系统之间采用
ActiveMQ
来异步扣费。
数据库拆分
将原来单一集中数据库根据新的服务系统进行拆分,分出了 5 个数据库,分别做了主从同步。
在拆分数据库过程中,涉及到将字段过多的表抽取成新表,删除过多的冗余字段,删除不用的字段,规范字段定义等等。
数据迁移
数据迁移操作大体分两种,全量迁移
此方式比较容易也不容易出错,只需一次性导出历史数据导入到新库;另一种是增量迁移
,在不影响现有业务的情况下,旧系统未完全下线的情况下一直在线上跑并产生新的数据,新系统逐步上线导入历史数据并接入新数据直到旧系统完成下线。
增量迁移方案
:一种是选择一个时间点将历史数据导入到新库,旧系统产生的新数据写两份到数据库,旧库一份,新库一份; 第二种是在旧的数据库表上增加个是否已迁移的字段,写脚本进行迁移并标识旧数据直到旧系统不再产生新数据完全下线。
采用增量迁移的方式踩了好多坑,出现了几次故障辛好最终完全上线,中间都要放弃增量迁移改全量迁移了,而互联网项目通常都是小步快跑的方式快速迭代更新版本,要适应业务场景。
因新系统接口定义有两个版本,一个是兼容旧系统的接口,另一个新的接口定义,按模块划分,逐步将在旧系统读取数据修改为先调用新系统从新库读,没有再从旧库读取数据。
数据校验
数据迁移完后需要对数据进行校验,写脚本比对新旧数据库中的数据,检查是否有漏数据或值不相等的数据。
定义规范
- 定义编码规范:制定了统一的编码规范,主要有变量命令、方法命令、方法调用、异常捕抓、日志输出等等。
- 定义接口规范:重新设计对外和以内的接口定义,分别定义统一的接口规范和数据结构,各个微服务组成一个大整体系统,对外提供的接口风格应规范统一。
这里存在个问题,无法要求已有的客户对接的数据结构按新的接口定义做统一的修改,所以在接口规范上定义了两套,一套是旧的接口(v1.0), 一套是新接口规范的接口(v2.0), 如果客户有新需求或旧接口需要修改,则全部采用和更新到 v2.0 的接口定义。
开发联调
开发人员之间对业务系统进行联调,因业务系统之间通信采用了新的接口定义,外部接口又存在两套,所以在联调时会碰到些问题需要解决。
提交测试
重构的新项目的测试最好找测试经验丰富并懂业务的工程师,需要对接口功能、性能、稳定性等进行测试。
部署上线
部署上线, 切分少部分流量到新的系统,及时跟踪日志,及早发现问题并修改。新系统稳定后就将所有流量接入新系统。
持续跟踪
新系统上线稳定后还需要持续跟踪,常看日志,观察系统是否出现异常,持续修复和改进。