从单体到微服务,Part 1:代码管理变化

👉 个人博客

从一个巨石应用拆分为多个小一些的领域服务,一般会同时把代码库也拆分为多个,一个领域服务对应一个代码库,方便独立演化,好处不再赘述,说说在现实中会碰到的几个问题:

💣 分支爆炸

巨石应用只有一个代码库,现在拆分为 10 个领域服务,那么有 10 个代码库,每个代码库至少得有 3 个分支( 开发分支、预发布/提测分支、发布/生产分支,如果采用 Feature 分支模式进行开发或者同时有多个版本在维护,还会再多几个分支,产生的分支交互关系很复杂,需要小心 ),10x3 就是 30 个分支,且一个服务的 3 个分支不是各自独立的,一定是围绕了一个机制( 通常是从开发到测试再到生产的软件研发流程 ),让代码变更在 3 个分支之间有序流转。

在最理想的情况下,对领域服务的拆分是正交的,此时一个需求也可能需要同时变更 2 个服务,也就是让 6 个分支产生了一定的关联。现实中,显然不可能对服务拆分、需求作这么理想的假设,这就棘手了,而且分支爆炸暗示了环境爆炸 —— 各服务在多大程度上独享/共享运行环境,1 个代码库的 3 个分支是否对应到不同环境等。

管理很繁琐,必须要借助工具。

💣 版本号爆炸

每一次发版,都需要根据【版本号定义】出一个版本号,最常用的是由 3 个数字组成的语义版本号 [X].[Y].[Z],除了 [Z],其他两个位置的数字变化都可能表明新版本做了不兼容的调整,暗示了 2 个风险:1)当前版本需要的运行环境发生了变化,需要对运行环境进行适配调整,影响环境管理方,比如升级了 jdk;2)当前版本暴露给外部使用的接口( Restful API、AbstractClass、Interface… )发生了变化,需要使用方进行适配调整,影响服务或包的使用方。

服务每一次发版就有一个新的版本号,由于服务在一定尺度上和其他服务存在耦合,各服务的版本号一定存在兼容关系,所有服务的兼容关系放在一起就形成了一个兼容关系网,当某个服务有新版本发布时,不能不关心这个版本和其他服务已发布版本的兼容关系,如果这个版本做出了不兼容的修改,其他服务未同步进行调整,就可能引发故障。

考虑一种可能场景,某天 A 服务运行过程中发现问题,需要将 V5 版本回退到 V3 版本:服务 B 当前的 v9 版本依赖于 A 服务 V4 版本新增的特性 F,这时候不能回退,只能直接修复问题,前进到 V6 版本;或者当 A 服务回退到 V3 版本,它依赖于服务 B 的 v8 版本,这就要求服务 B 一起回退。这个场景表明,想回退一个服务,必须将其他服务也一并考虑进来,小心分析其版本兼容关系。魔鬼藏在细节里,如果兼容关系复杂、服务设计不合理或者管理不善,就只能前进,不能后退。

一剂良药是自动化+模块化。有人说我用 Gradle 对代码进行了模块化,但 Gradle 的模块化比较糙,它只是对代码文件的物理组织结构进行模块化,无法限制一个模块内的实现伸手使用另一个模块的内部实现细节( 容易造成复杂失控的依赖关系 ),缺少了对模块边界的管控 —— 模块应只允许外部调用其对外暴露的接口( 参见 Java 9 Jigsaw ),其内部实现细节对外隐藏,并且模块的世界也应是一个有序的世界,比如符合层次化原则、不能有循环依赖等。对边界的合理规划和控制应作为一个设计原则,贯穿软件的任何尺度,从方法、类、包,到模块、服务、系统边界。当边界从混乱变得有序,通过判断边界上的契约是否发生了变化,就可以对兼容关系进行自动化管理了。

💣 依赖爆炸

开发也要站在行业的肩膀上,不引用第三方工具包,几乎做不出任何功能,依赖和复用是一个硬币的两面( 关于复用,详见 前作 )。

巨石应用拆分后的每一个服务都有其依赖树,树里的包绝大部分是行业提供的第三方包,且依赖还在继续分化,朝着颗粒度更细、可复用性更高的方向发展( 可复用性高 ≠ 被复用率高 )—— 从行业整体来看是有益的。假设巨石应用生产环境以前有 100 个依赖包( 基础 60 + 特性 40 ),现在拆分为 10 个领域服务后,每个服务可能有 70 个依赖包,生产环境至少会有 700 个依赖包。由于各个服务在一定程度上是独立演进的,不同服务、不同开发人员的本地环境、不同的测试环境、不同的生产环境,这些现实因素的存在使得同一个类型的包,必然存在不同的合法版本。

怎么协调和二方、三方包的依赖关系,怎么协调各个服务、各个环境依赖包使用和升级的步伐,怎么引进、退出、替代依赖包,都是需要考虑的问题。

The End

任何种类的问题都需要适配人有限的认知能力,才能被人处理,所以可以从人的认知能力出发,基于 2 个维度( 有序性、复杂性 )将问题空间划分为 4 个象限进行认知:有序简单、无序简单、有序复杂、无序复杂,从左到右,问题的认知和处理难度不断提高,直至无法被认知、无法被处理。科学家和高级神棍工作在无序复杂象限,专业工作者工作在有序复杂象限,其他人工作在剩余两个象限。问题所处的象限不是固定的,大体是随着新理论新发现而从复杂变得简单、从无序变得有序,是一个不断流动的过程。

上述的爆炸问题属于有序复杂问题,对于有序的问题,只要摸清规则,就可以大胆将其自动化,人不再需要参与 B、C、D、E 4 个中间环节,直接构造出从 A 到 F 的人为黑盒规则,将大量重复繁琐的工作交给机器去完成,让人和机器各展所长。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值