今天接着再谈下微服务拆分方面的话题。
01-微服务拆分概述
要谈传统单体应用的微服务拆分,首先需要对应用本身的形态进行理解。一般来讲应用包括两种类型。一种是流程驱动类应用,类似OA系统,ITSM系统等。一类是数据驱动类应用,典型的是资产管理系统,资源管理系统。
数据驱动类应用底层是一个大共享数据库,这个数据库很难进行拆分,否则导致上层应用实现存在大量的跨库和分布式事务问题。而对于流程类应用,往往流程对应的底层数据对象相对独立,耦合性小,因此更加容易进行拆分。
对于微服务的拆分,我当时给出了三种常用的方法。
其一是根据业务系统本身的阶段和流程进行拆分,这种拆分还可以结合企业已有的组织部门和科室划分进行。
典型的比如供应链管理系统,本身就分为了采购需求,招投标,框架协议,采购订单,采购执行等关键的阶段。那么按这些大阶段进行拆分是合理的。原因就是阶段之间的交互点相对来说比较少。
比如招投标模块,内部招投标流程很复杂,暂时最终只需要将中标的供应商信息传递到下游的阶段流程即可。
其二是可以按数据聚合进行拆分,当我们在分析整体的数据架构,构建了数据逻辑模型后,数据和数据之间有关联,但是总是能够找到数据之间的关联线索和具体的数据聚合根。
那么从数据聚合根这个地方拆开形成独立的以数据为中心的微服务模块是合理的。
同样我们对供应链域的数据架构和逻辑模型进行分析,可以看到数据逻辑模型中体现的关键的聚合关系。从聚合根这个地方拆分开即可以形成类似供应商,合同,采购订单,采购计划等关键的微服务模块。
其三是按照领域建模的思路来进行拆分,先通过事件风暴来识别事件,同时事件来聚合关键的领域对象。
但是领域对象不应该作为拆分的粒度,这个粒度太细。而是还要做一次聚合,形成业务子域的概念。应该是按照业务子域进行拆分,类似如下:
当你观察的时候,你会发现供应商,物料的管理实际是同一个基础数据管理部门在做。那么这两个聚合完全是可以划分到一个限界上下文里面。类似还有采购请购,采购订单,采购执行都是一个部门在做,那么也可以归到一个上下文。当然你可以从一个完整业务流程分析出发,看究竟分为哪些大的阶段,一般来说这些阶段点都可以作为微服务划分的边界点。
往往比单纯的事件风暴后,再聚合更加有效。比如电商核心业务场景和订单生命周期如下。
当你对核心领域对象的生命周期阶段梳理清楚后,实际上已经可以明确地识别出关键的上下文边界和关键的领域对象。比如上图可以看到商品,订单,供应商,用户,库存都是关键的领域对象,相关的业务操作也围绕这些业务对象展开。
02-从大应用架构体系思考拆分
对于大型企业整体应用架构规划设计的时候,实际很早就在做拆分的事情。比如早期可能只建设了一个供应链管理系统,但是随着业务的发展往往后面又独立建设了供应商管理系统,招投标管理系统,采购系统,仓储系统,合同管理系统等。
这个本身就是传统大单体的一次拆分。
类似大型企业应用建设中围绕ERP核心外围建设了大量的配套系统。仅仅一个财务域往往就可能建设报账系统,预算系统,资金系统,发票管理系统,电子凭证系统等。这个本质也是对财务大系统的拆分。
但是这种拆分往往在早期往往被人诟病,原因就是IT系统越建设越多,后面的系统集成,系统的管理和维护都越来越困难。大家可以思考下现在转微服务架构,这个拆分往往更细,不是同样的带来了微服务间集成,后期微服务治理等一堆问题吗?
如果企业原来已经拆分到了招投标系统,采购系统这种粒度。财务拆到了报账系统,预算系统这种粒度。实际已经做了关键的一层拆分。如果还要对类似招投标系统进行微服务改造,做拆分,特别是数据库的拆分显然是不合理的。
这种拆分我们仍然是站在单个系统的角度进行了拆分,类似原来的组件化和模块化,这种拆分本质仍然是偏纵向的,只会拆分出更多的小烟囱,虽然可以拆分解耦增加扩展性,但是拆分出来的内容本身并不能体现复用性。
因此再次提出一个关键点,即基于单个单体系统去考虑拆分根本无法体现横向分层能力复用的SOA架构思想。对于横向拆分应该以数据驱动为核心,从整个IT应用架构体系来进行思考。
我们可以看下传统企业应用架构体系建设的情况如下:
传统模式往往都是围绕ERP系统建设了大量的外围系统,外围系统的粒度有粗有细,但是对于大企业往往已经做了上层应用的拆分工作。整个应用体系围绕ERP进行集成。
ERP系统和外围系统都有各自独立的数据库。集成可以通过ESB总线或集成平台间,虽然都是接口集成,但是接口集成的本质偏数据集成。即通过接口进行数据同步,数据在多个业务系统中落地使用。
同样一份数据往往在多个业务系统间同步。类似供应商数据,往往会在ERP,SRM,采购,合同,MES,WMS,报账,资金等多个业务系统落地使用。这种集成方式的好处就是业务系统间解耦,坏处就是数据多点落地导致数据的不一致性,数据使用时候的时效性无法满足。同时涉及到供应商领域的能力外泄到业务系统中去处理。
也正是这个原因我们在进行原有应用架构分析的时候,可以从数据角度来分析哪些数据在多个系统多点落地并使用。如果一个数据多点落地使用,那么这个数据就是具备复用价值的数据,这种数据应该下沉,形成以数据驱动的领域对象,暴露可复用的服务能力接口。
如上,供应商数据具备这种复用价值,那么供应商数据应该独立构建底层能力中心来统一提供领域服务能力给上层应用使用。我们从传统架构体系中拆分了供应商中心,这个供应商中心聚合供应商能力,暴露能力接口,这种接口被上层应用使用,原来上层业务系统都不应该涉及到任何供应商的业务,而只应该是按需调用供应商的能力接口。
在这种数据驱动思路下才容易构建横向分层的拆分,横向分层拆分后下沉的各个中心能力整合后形成企业的业务能力中心。
在这种情况下我们底层可能形成基础数据,订单,库存,结算等多个能力中心,这些能力中心的识别就是基于传统架构下的数据集成同步来识别的,识别出来关键可复用的数据对象。
形成的多个能力中心构建了企业核心的能力中心层。企业的整体应用架构模式也变成了横向分层模式。
即:能力中心层+API接口+上层应用。
能力中心层拆分后数据库需要对应进行拆分,由于本身就按数据驱动的思路进行的能力中心识别,那么数据库基于前面的数据架构的思路就很容易拆分开,基本可以做到能力中心和数据库1对1。这种情况下的数据库拆分是有意义的。
而对于上层应用并没有没有数据库,仍然还存在自己的ADB私有数据库。因为上层的应用还需要处理类似流程,申请单等各种流程类业务,这些业务业务会形成数据,也需要进行持久化,但是这些数据表没有任何复用的价值。类似招投标管理里面的招投标申请单,评标流程单,这些本身没有复用价值,应该放在上层ADB私有库里面。
而对于上层应用,类似采购管理系统是否还需要进行拆分?这个就回到了我前面强调过的内容,采购系统仍然可以按模块进行拆分,各个模块可以独立用SpringBoot开发,独立编译和部署。但是底层的数据库不需要继续拆分,这种数据库拆分本身没有大的意义,也不要通过拆分去解决业务并发量的问题。对于业务大并发量的问题本身不通过拆分也有大量方式可以解决,类似数据库同步复制下读写分离,缓存,消息中间件等各种技术实现思路。
所以最后再次总结就是从企业大应用架构体系来看。应该是从整个应用体系域分析和思考,首先进行数据驱动的横向拆分,其次才是原有单体系统的模块拆分。横向拆分需要拆库,原有的单体应用更多只做模块拆分不拆库。这才是一个SOA架构思想和微服务架构融合的思路。