
Hello大家好,我是人月聊it。
今天准备再简单的跟大家聊一下微服务拆分,因为上周刚好有一个客户打电话过来沟通他们在实际微服务建设实践过程中,关于微服务拆分相关的一些问题。因为最近通过最近2~3年我跟客户的沟通也发现了,对于前期的微服务拆分已经成为了整个微服务架构设计,包括微服务治理里面最最关键的一个内容。
大家都在找寻一种通用的类似于公司化的微服务拆分的方法,但是实际上是没有通用的公式化精确方法进行微服务拆分。
微服务拆分原则
微服务拆分更多的仍然是微服务拆分的关键原则,究竟应该怎么做?包括我在前面也发过很多的文章视频来解释这一这些点,包括对于流程驱动的情况下,你应该怎么样拆分?如果是数据驱动的应用,你应该怎么样去拆分?包括你怎么样借鉴领域架构领域驱动设计的思路去做拆分,但是更多的仍然是一种拆分原则。
所以在前几周我跟一个朋友沟通的时候,他就很明确的告诉我微服拆分不是你只要把领域驱动设计领域建模学精通了,就可以很清楚的知道一个大应用建设应该如何进行微服务拆分了。但是大家可以看一下领域驱动设计的书,他也仍然没有给出精确的微服务拆分的方法。
在领域驱动设计里面大家都知道,应该通过事件风暴的模式去识别关键的领域对象,但是你不可能说把每一个领域对象都拆分一个微服务,这样的话颗粒度就太细了。
拿一个传统的供应链系统来举例,你会看到采购采购单,采购订单,物料,供应商,框架协议,入库单,出库单,库存信息,采购计划等是核心的功能聚合点。那么一个传统的供应链系统需要划分出好几十个微服务?
按事件风暴梳理事件并基于对象进行功能聚合本身没有错。
但是每个聚合本身不能完全1对1映射到微服务上面。
因此应该是将多个相关的聚合归并到一起,并以此来划分限界上下文。限界上下文可以只包含一个聚合,也可以包含多个聚合。因此这里就涉及到限界上下文和业务子域的划分。即如何将多个领域对象或聚合,划分到一个限界上下文里面。
在这里领域建模里面仍然没有一个公式化的方式来解决,其谈到的仍然是你需要遵从高内聚,松耦合的划分原则。所以这个其实就导致我们做微幅拆分拆分的颗粒度怎么样去保证相当的困难。
所以简单来总结微服务拆分的原则就两条:其一从纵向上来需要满足组件拆分经常谈到的高内聚,松耦合原则;其二是从横向拆分角度来看需要满足能力复用和共享原则。
理清业务驱动和数据驱动两种关系
对于IT应用建设一般有两种关键的类型,一种就是工单流程驱动型,比如说你建了一个OA系统,你建的一个it运维系统,那么在这种情况下面,你微服务拆分的再细也没有关系,因为不同的工单不同的流程,它落地下去的数据库数据对象之间它也没有太多的关联和依赖关系。
但是还有一类系统,它是完全强数据驱动的系统,我们常见的就是类似于资产管理系统,类似于我们的库存管理系统。
虽然说上面也有很多的业务功能,比如说库存管理系统,它会有入库出库、有库存调拨,有库存盘点,但是你会发现所有的功能都会围绕底层整个的库存对象去做运转。
那么在这种情况下面,你去做微服务拆分的时候,你上层的业务功能应用拆分很简单,但是你的数据库怎么拆分?
在这种情况下面,如果你把数据库也拆开了,那往往就是灾难性的,那往往会导致大量的跨库查询或者是后期的分布式事务的问题。
所以说我们究竟怎么样去做微服务拆分,一定要根据实际情况出发。微服务拆分它的本质是为了解耦,是为了降低各个模块之间的依赖,你不要做了微服拆分以后,让各个微服之间的耦合性变得更强,那这反而就是一种错误的一个方式。
因此对于微服务拆分,一定要去真正的理解你的业务流程业务场景,基于流程驱动和数据驱动这两条线,不仅仅是做好上面的业务功能模块的再分,更加重要的是做好数据库的拆分。
包括我最近这么多几年做咨询做系统建设的经验来看,我个人反而觉得当前切实有效的一个方式,反而是类似于传统结构化分析设计的思路。基于CRUD矩阵分析,去做好高类聚和松耦合。
因为结构化的CRUD矩阵分析里面做到一个关键点,这个矩阵图里面既有业务功能又有数据,所以说这种矩阵分析它同时可以从业务和数据两个维度去考虑累积性,考虑综合和这个反而是当前比较切实可行的一种微服务拆分的思路。
对微服务的简单回顾
在讲业务驱动和数据驱动双维度拆分前,我们还是简单的回忆一下我原来讲过的对于传统架构到微服务架构的演进路线,这个本身又分为了开发设计态和部署运行态。
对于开发态的时候,我们往往就是看到的一个大单体架构,这么一个大单体,它往往是一个大的数据库,一个大的完全耦合的逻辑层。
但是到了微服务阶段的时候,这个单体本身就进行了大拆小,它会形成类似于订单中心、产品中心、库存中心各个微服务,同时各个微服务底层对应的数据库也要去做对应的拆分,以做到完全的解耦。
所以说订单中心会有订单库,产品中心有产品库,库存中心有库存数据库,各个中心微服务之间又通过轻量的Rest API接口去进行集成。
对于传统IT应用系统部署运行态,它往往是用X86服务器或者是虚拟机去进行部署,但是做了微服务拆分以后每个微服务组件它更加轻量化,它就更加容易用当前的容器云结合去做动态的弹性部署。这是我原来在谈微服务架构的时候,从设计态到运行态和传统单体应用架构的一些关键区别。
基于业务驱动和数据驱动的双维度拆分
原来我在谈微服务拆分的时候,更多的都是从一个大单体单体系统怎么样去拆分去考虑,就是说这个单体应该拆成几个微服务,包括底层的数据库应该怎么样去做拆库,那这个一个大单体的这个视角,你发现你拆分完了以后,它仍然是一个纵向的小单体。
比如我原来是一个大单体,有底层的数据库,有上层的应用,那我做了拆分以后,我底层的数据库可能已经拆分成了三个独立的数据库,三个独立的数据库在上层都会对应到相关的后端服务,后端服务也去做了微服务拆分,同时后端服务提供的API的能力统一接入到API网关或者是微服务网关给前端应用使用。
我们原来谈的聚焦的狭义的微服务,其实是我虚线椭圆这个地方标注的后端服务组成的微服务这么一个能力中心。
所以我原来传统的视角更多的是考考虑单个单体怎么样拆分,包括应用层怎么拆分,包括数据层怎么样去拆分,但是没有解决一个关键的问题,就是我拆分以后它底层的数据库往往仍然存在大量的冗余,包括数据库之间存在大量的数据集成和同步。
正是由于这个原因,我今天讲的微服拆分的一个关键点,就是我们应该有一个全局的视角,应该从整个企业的应用架构和数据架构的角度来出发来考虑微服务拆分。
在这种场景下,微服务拆分必须将数据拆分和应用拆分进行分离。
我们首先来看一下传统的整体的应用架构,你是烟囱竖井式的建设,一个应用会对应一个数据库,但是从左边这个图里面我们可以看到,我标了颜色的小方块,原来的各个应用对应的数据库之间,它往往存在大量的数据重复或者是冗余。
比如SRM系统有供应商数据,物料数据,你的供应链采购系统往往也有供应商数据和物料数据,这些数据有可能是通过不同的入口在进行新增或者修改,也有可能是后期经过底层的数据集成去进行了同步。
反正我们看到的就是同样的数据往往在多个数据库里面存在冗余,这种冗余有可能也体现了前端的功能也存在冗余。那么在这种情况下面,我们去做整体视角的拆分的时候,我们一定要把数据的拆分和应用的拆分分开来理解。
对于数据的拆分,更多的其实是从数据架构的视角去分析原有的it系统它本身的数据沉淀和数据分布,真正找到原有it系统的跨系统共享的共享数据,将这一些共享数据拿出来,形成一个个数据共享库,或者叫共享数据能力提供中心。
比如结合这个图我们可以看得到,里面有涉及到棕色、绿色、黄色的各个块,它可能都是共享数据,那这一些共享数据拿出来应该形成底层的DB的共享库,这个共享库我们就把它叫做共享的数据能力中心,它往往是提供共享的数据服务能力,给上层的后端服务使用。拿出来单独形成共享数据中心微服务的核心原因就是减少后期的数据集成和同步。
而对于后端服务的拆分,我们往往是基于业务和流程驱动,按照松耦合的思想去进行拆分,而后端服务的拆分,它的颗粒度往往就可以更细,同时后端的服务我们不再要求后端服务和底层的共享库之间,它是严格的一一对应关系,一个后端服务可以访问多个后端的共享库,后端的某一个共享库也可以为多个后端服务提供服务。
在这种情况下面,拆分出来后端微服务以后,后端服务再将相关的API服务能力注册接入到API网关,最后提供给前端应用使用。
当把DB的共享库提取出来以后,每个后端服务还有没有数据库?
在这类要注意后端微服务可以还有一个小的私有数据库。这个数据库的数据往往仅仅在这么一个后端微服务模块里面使用,不存在跨业务化系统之间的协同和交换,所以这个时候后端服务也可以挂数据库,但是更多的是私有库。
基于数据驱动和数据共享沉淀下来的底层的各种共享能力的数据库,就真正的能够发挥数据共享的这么一个关键的作用。
能力中心数据驱动拆分,应用业务驱动拆分
所以我们看到DB的这种共享库怎么样去建设,又回到了我们做传统的主数据,传统的数据架构建模的核心思路。
你应该去分析企业核心有哪一些共享数据,类似于供应商物料、客户人员组织这种基础主数据,也可能会涉及到订单、合同这一些共享的动态数据。这一些共享的数据就应该去形成后端的共享数据库,为上层的应用,为上层的后端服务提供相应的数据服务能力。
最后再简单总结就是通过业务和数据两个维度进行微服务拆分。首先是通过数据架构数据共享的视角去拆分后端的数据服务,然后再是基于业务架构流程驱动的视角去拆分上层的应用的一个个微服务,接着再去考虑应用的微服务跟后端的共享数据库之间怎么样集成和协同。
这个反而是一种更好的既结合了纵向组件化架构,又结合了SOA横向架构分层的思路,这样拆分这样的微幅拆分往往更满足整个企业it的应用架构和数据架构的规划。
今天的分享就到这里,希望对大家有所启发。