WES 重构系列(一):记录一下 WES 重构历史
在 Martin Fowler 的 《重构》一书的首页里有一句古老的工程谚语:
“if it works, don't fix it?”
一、为什么要重构?
当时我们的智能仓储核心系统(WES)面临三个关键痛点 :
- 领域边界模糊、迭代困难,比如说单据调度业务部分逻辑存在于两个系统里面;
- 二是核心链路是 “黑盒”,数据不一致、故障定位难,年均故障工单过万;
- 三是公司在扩张期,尤其是海外项目(日本、东南亚、美国等)交付压力大,原有系统支撑不了多区域业务需求。所以启动了全业务分阶段重构,目标是提升系统稳定性、可维护性,支撑海外项目交付。
二、我们重构阶段历程是怎样的?
其实主要分为三个大版本:2.9、2.10、21.11
- 2.9 版本:WES 收拢了单据调度业务,将单据调度业务从 WCS 上浮到 WES
- 2.10 版本:WES 将货架到人系统与料箱到人系统合并为一套系统,并支持多库区混合调度。
- 2.11 版本又分为 8 个小版本,从 2.11.1 到 2.11.8,从 2.11.1 到 2.11.6 做了核心链路的梳理和重构,2.11.5 到 2.11.6 围绕核心链路做了许多补充,2.11.7 到 2.11.8 做了一些代码优化与性能优化。
三、重构的具体方法与策略
1、重构前的准备:
- 需求与业务梳理:我们做了类似事件风暴的会议,团队内的人都聚在会议室里,上午开会交流历史业务,下午写文档,最后梳理出了几百份文档和图表,基本上把核心链路都梳理清楚了。
- 技术选型:我们没有大改技术架构,核心框架基本上维持了 SpringCloud 这一套,MySQL 从 5.7 升级到 8.0,RocketMQ 从 4.3 升级到 4.9,引入了 XXL-JOB和动态线程池,后期我写了一个数据一致性组件以及任务流转树监控系统。
2、重构中原则和步骤:
- 模块化与解耦,领域划分:WES 这边主要负责单据调度和实操相关的内容
- 渐进式重构:按业务模式迭代,一次新增一个主业务模式,尽量小步快跑。
- 代码规范与可维护性:基本上按照阿里巴巴 Java 开发规范,本地使用阿里巴巴规约插件,远程使用 Sonar 扫描
- 所有的大于一天工时的需求都要写dev design,组内阅读或评审。
- 开发流程包括:需求评审、技术设计文档评审、测试用例评审、代码评审、研发自测、测试同学测试、仿真压测、现场真车测试、现场真车压测
四、我负责了哪些事情?
业务上:
- 独立负责了 2.9 的理货单据调度业务上浮,包括表迁移,代码迁移,与下游团队沟通并确定数据交互形式。
- 参与了 2.10 版本的系统合并,比如货架到人在线拣选与料箱到人在线拣选,做了一些表结构的共用,比如出库单表、出库单明细表、出库作业单表、出库作业单明细表,但是对于任务表依旧是分开的,考虑到任务涉及到调度实体,也就是料箱、料格和货架,混用一张表,会增加理解成本,并且单业务模式,会造成许多空字段,显得有些冗余。
- 核心负责了 WES 多种业务模式的调度链路,比如料箱到人的组箱、上架链路,出库的全链路,理货的上架、下架链路,全盘的全链路。
技术上:
- 业务数据监控:从0 到 1 独立负责了任务流转树监控系统开发与维护。
- 核心链路节点的数据一致性保障:从0 到 1 独立负责了数据一致性组件的开发与维护。
- 系统性能优化与瘦身:通过解决JVM内存泄漏、清理无用代码、优化慢查询与缓存、重构代码坏味道(如长方法、循环内DB操作)等措施,使死锁、锁超时、计算错误等线上顽疾基本归零。
- 设计模式:通过提取公共抽象、应用模板方法等设计模式,对大量重复代码进行整合与重构,提升了代码复用性和可维护性。
- 参与接入了 XXL-JOB 和动态线程池框架。