谈微服务粒度划分(200718)
今天准备谈下在进行企业中台规划或微服务架构设计时候,微服务模块究竟应该如何划分,已经划分的粒度究竟如何才合适。这个估计是所有人在进行微服务转型的时候都遇到的最典型的例子。
实际上对于微服务模块划分,微服务API接口识别是整个企业中台规划建设方法论中的一个关键内容,我在前面也谈到过当前中台+微服务架构思想实际上仍然可以参考原来的SOA+企业架构咨询的方法进行架构规划,但是对传统方法论本身存在优化和改进。
对于该点后续准备通过中台规划建设方法论详细展开来谈,今天仅仅是从一些关键的点上来说明下微服务模块划分问题。
单体到微服务划分大原则
注意这里讲的是大原则不是绝对原则。对于传统的单体应用在转到微服务的时候我们也是给出实际实践总结的一些大的原则做为参考。
原则1:划分为<10个微服务模块
一个传统的单体应用,在进行划分的时候最好不要超过10个微服务模块。注意这里指的业务功能模块不包括底层的系统管理,流程引擎等技术模块。
大家可能也会看到传统的单体应用一般也不会超过10个以上的一级功能菜单,因此在划分微服务的时候也可以参考一级功能菜单进行划分。
注:这个原则不绝对,比如一些类似OA,IT运维流程管理类系统,所有的业务功能流程之间基本没有任何耦合性,这种业务系统可以将微服务划分的更细也没有大的影响。
原则2:强数据关联模块不要拆分
简单来说就是有些系统基本就是围绕一个核心数据或业务对象展开的管理系统,比如我们说的资源管理系统,资产管理系统等。
对于这些系统的资源,资产等核心数据,建议都不要再进行微服务拆分,这些数据之间本身存在强数据关联和一致性要求,如果进行微服务拆分后续很难保证事务一致性要求。
原则3:以数据聚合驱动业务功能聚合
这个理解起来困难,简单来说就是微服务划分不仅仅是上层业务功能模块划分,而且包括了数据库的拆分,因此在划分微服务的时候首先要考虑数据域的拆分,基于数据和功能的CRUD分析来考虑数据的聚合关联要求。先拆分好数据域,再来考虑数据域里面有哪些业务功能。
原则4:从纵向功能划分思路到横向分层思路转变
在微服务划分里面,同样需要结合SOA的横向分层思想,即:
传统的单体应用你会发现在进行微服务划分的时候,本身微服务也体现出分层属性,即有些属于底层的业务对象,实体,数据提供类微服务;有些数据业务功能和规则类微服务;而还有些属于上层的流程和服务功能组合类微服务。
因此在进行微服务划分的时候应该从数据-》功能规则-》流程的分层模型维度综合考虑。
原则5:高内聚,松耦合的基础原则
当然,在进行微服务拆分的时候高内聚,松耦合的原则不变。而如何确保拆分的数据库,拆分的业务功能模块满足高内聚松耦合的原则。
在前面做企业架构规划分析的时候就经常谈到,在进行业务流程分析,业务架构和数据架构规划的时候,核心会产生业务流程,业务功能,业务数据对象等关键的信息,而我们要做的就是对这些关键进行交互矩阵分析来识别业务模块,业务数据之间的内聚特征。其中包括:
业务组件交互矩阵:横向和竖向都是业务组件,内容单元格里是具体的业务交互接口点,通过此矩阵可以看出业务组件的划分是否会导致大量的业务接口存在,分析每个业务接口产生的原因,以进行组件的合并、业务功能转移等。
业务对象和业务交互矩阵:横向是业务组件和业务功能,纵向是具体的业务对象,内容单元格是具体的CRUD信息(即传统的CRUD矩阵分析)。对于同一个业务对象,CUD操作尽量减少分离,而读操作则可以共享,以减少业务对象的多头管理和维护,将业务表单和数据的维护尽量控制在同一个业务大组件中完成,减少数据间的交互和传递。
流程交互分析矩阵:横向是具体的流程信息,纵向是具体的流程活动信息,在这个矩阵图上可以看到同一个流程活动或流程片段往往存在于多个不同的流程。该分析的重要作用是对流程建模中可复用的流程片段或流程活动进行抽象和分析。
功能业务组件分析矩阵:横向是具体的业务组件,纵向是业务功能,在该交互分析上重点是分析具体的可复用的业务功能,以对可复用的业务功能进一步进行抽取,形成可复用的服务。
微服务划分的指导思想
对于微服务模块划分,简单来说你完全可以借鉴传统单体应用业务功能模块划分的思路进行,只是在这个基础上会增加了我上面原则里面谈到的数据驱动,SOA分层思路等。
微服务划分切忌不要划分的太细,粒度划分的越细,后面微服务集成和管理的难度就越大。
再次纠正一个观点,即我们这里指的微服务模块是从数据库到业务逻辑到前台都可以独立自治和部署的模块。即使在一个微服务模块内部,你还可以拆分不同的组件,比如拆分为多个JAR包,但是这个不是我们独立管理的单位。
在IT应用架构规划大中台的概念下,实际上中台包括了技术中台和业务中台,对于技术中台重点是各个技术组件和技术服务能力的实现,而对于业务中台则主要包括了数据能力和业务规则处理能力的提供。
对于业务中台本身也是分层,包括了最基本的数据类中心和业务处理类中心。
数据类中心本身又包括了基础主数据类和核心共享业务单据类,比如我们看到的产品中心,用户中心,属于基础主数据类。而对于订单中心,库存中心则属于业务共享数据类。
业务处理类则主要是进行核心业务功能和逻辑的处理,类似的包括了交易中心,结算中心,计费中心等,都可以看做是业务处理类的中台模块。当然,业务处理类中台也包括关键的领域服务提供组件,即这类组件需要调用底层更多基础原子模块的核心接口能力,经常组合后再提供出整合的组合能力。
技术中台模块的划分-完全垂直彻底解耦
技术中台主要负责提供各类的技术服务能力,其中包括了消息,缓存,存储(内存,结构化和非结构化),文件,日志,通知,规则引擎,流程等各种通用的和业务无关的技术能力。可以看到对于各种技术服务之间,本身没有任何的耦合性,完全是垂直独立,因此对于技术中台中的微服务模块划分粒度,完全可以一个技术服务一个微服务模块,完全独立管理和部署,相互之间没有任何影响。
技术中台属于我们传统的PaaS技术平台必须要管控和治理的一部分内容,对于技术服务的接入,消费和调用,日志等都需要在PaaS管控治理平台能够查询和监控。
业务中台模块的划分-围绕数据仍然是核心
注意这里的业务中台模块,就是一个独立的微服务模块,一个独立的有数据库,逻辑层到前端界面展现的小应用。只是这个业务中台本身还将自己的关键能力以API接口服务的方式开放给前台应用调用。
业务中台模块划分粒度相当重要,粒度太细后期集成和管控都相当复杂,同时由于模块划分太细也容易引入更多前台应用开发带来的分布式事务处理场景。而粒度太粗的话本身又无法起到独立自治,后期易于变更运维,本身灵活敏捷的作用。
如果说做互联网电商,由于有类似阿里等的成功实践,可能大家闭着眼都知道应该包括类似产品中心,库存中心,用户中心,订单中心,结算中心等各类的中台模块。但是如果是全新的业务类型,或者说针对企业内部的管理信息化,究竟应该如何去划分中台。
1. 基础主数据类模块划分
如果一个基础主数据就一个微服务模块,那么会导致我们的微服务模块的量极大,比如用户中心,组织中心,人员中心,客户中心,物料中心,供应商中心等。那么这种划分方法在企业内信息化上并不太合理。
如果是按标准的主数据管理系统的业务模块划分,实际上它不是按照数据维度进行划分,一般我们说主数据系统会包括了元数据和数据对象管理,数据集成和调度,数据清理,流程引擎,数据内容管理等各个模块。而无法真正体现出以数据为中心的思想。
因此对于基础主数据类微服务模块,最好的方式是按数据域进行拆分,比如对于用户,组织,岗位,人员等划分到一个人力域数据中心,对于供应链,物料编码,采购类别等划分到采购或供应链域微服务模块。这样划分的好处就是既实现了一定程度上的模块拆分和松耦合,同时按域划分后,同一个域的基础主数据本身在一个数据库中进行管理,这些基础主数据本身可能存在一定的耦合关系,那么这些耦合关系的处理将不再需要提升到分布式事务层面去处理。
2.业务功能类模块划分
谈业务功能类模块的划分,实际上又回到我们在传统进行单个业务系统架构设计的时候如何进行组件划分这个话题。如何划分组件,简单来说就是要高内聚和松耦合,确保每个组件尽可能的独立自治,组件和组件之间的干扰最小。
当时我们在做单系统的时候,往往对于组件划分考虑的并不彻底,就是说在代码层面确实划分了组件,组件也可以进行独立打包,但是对于各个组件仍然对应一个数据库。那么我们就经常犯一个错误,即虽然在业务和逻辑层两个组件看似松耦合了,但是很多耦合性转变到了数据库层了。举个简单的例子,数据库的一个关联查询很容易就实现了,但是涉及到关联的两个表,其核心Owner却是不同的两个组件模块。
所以对于上层的业务组件划分,本身原来我们也谈两个方法,这里拿采购管理系统举例。
- 按大阶段划分,可以分为采购需求,采购订单,采购执行,采购绩效评估,供应商,物料等模块。
- 按数据维度划分,可以划分招投标中心,采购中心,绩效中心,供应商中心,物料中心等。
不论是哪种方法,我们看到在进行微服务模块划分的时候,关键还是要把基础和共享数据找出来,然后才是去处理上层的业务。再来考虑业务流程,业务规则处理等还需要单独设置哪些微服务模块。即使是用方法一,我们也看到每个模块都一定有自己关键的主属Owner数据。
划分微服务模块,实际上相对关键的一个步骤就是拆分数据库的过程。要把原来我们一个数据库的内容,拆分并对应到各个微服务模块上。主属Owner,对该数据具备了完全的CRUD能力。而其它模块更多的是单纯的数据导入或数据查询。
大中台更多的是体现其核心数据集中和共享能力,而不是业务流程和规则处理能力,因此更多的业务流程处理都应该归结到前台更加合适。
一个大中台的订单中心,可以和各种各样的前台微服务模块对接,不管是网页还是APP应用,不管是渠道,政企还是电商,但是最终都是将正式流程处理完成后生效的订单数据导入到订单中心。然后订单中心再提供完整的订单能力开放。
下面我将对上面讲到的一些核心指导思想展开进行描述。
流程分析识别大阶段
当我们在分析一个业务或业务系统的时候,经常会用到端到端的业务流程分析,而业务流程分析完成后一个完整的流程阶段也就清晰了。
一个大流程的各个阶段往往就是我们划分微服务时候重要参考。
比如上图我们在进行一个供应链端到端流程分析的时候,在流程梳理清楚后我们可以很清楚的看到采购需求,采购请购,采购合同,采购订单,物流管理等大的流程执行阶段。而这些阶段就是我们划分微服务的一个重要参考。
其次,在同一个阶段里面涉及到不同的职能部门单元的时候,我们看到耦合性本身也较弱,那么就还可以进一步进行拆分。比如对于采购需求阶段可以进一步拆分为采购需求和采购计划,而对于采购溯源阶段,可以进一步拆分为采购请购和招投标两个独立的微服务。
即你在进行微服务拆分的时候,除了基于流程分析,企业当前的业务部门和岗位角色设置情况也可以作为一个重要参考。
比如上图的业务部门设置也可以清晰的看到对于采购计划,采购合同可以独立为微服务。而我们流程分析里面没有识别到的类似采购绩效管理,采购执行监控也是独立的微服务模块。
对于采购执行监控更像是我们说的前台流程组装类微服务,因为其本身不产生核心业务单据和数据,而是对已有的微服务数据和业务服务能力进行组装呈现。
从已有业务系统模块划分入手
对于已有的单体业务系统,当然还可以从已有的业务系统入手进行微服务模块划分。要知道对于传统的单体应用业务模块划分的时候本身也是考虑了高内聚,松耦合的道理。
但是传统的单体应用构建的问题在哪里呢?
我们常说的单体应用本身的构建更多的是从纵向业务功能的角度出发,是偏纵向垂直方式构建业务功能的,而对于微服务架构思想下,我们引入了SOA架构思路,即会去思考当前的业务功能和流程,如何从数据-》功能-》流程的横向分层思路来构建。
这也是我们在参考传统的业务系统架构的时候需要调整的地方。
图片来自网络
上图是我们常见的一个采购管理系统的功能架构图。
从这个图里面可以看到如果进行微服务拆分,对于采购计划,采购寻源,采购合同管理,采购订单管理,采购基础数据,供应商协同,供应商管理就是可以进行拆分的微服务。
当然在这个过程中,你会发现有些地方还可以拆分。
比如上图里面的订单执行,对于订单执行你再按业务流程分析就会发现本身还可以按流程阶段,业务职能域划分为采购订单管理,物流管理,发票和结算管理等几个独立的业务域。而这些就是我们可以做为独立的微服务模块。
其次,我一直在谈的分层思路,结合上图我们进一步解释。
- 供应商作为核心基础数据应该拿出,形成独立的供应商中心,核心是基础数据能力
- 原供应商管理模块中的供应商认证流程等应该移到前台类应用模块
- 供应商协同是属于明细的前台流程层功能,符合我们分层思路,即划归到前台独立微服务
因此即使参考已有的业务系统模块划分,也要考虑核心共性基础数据下沉为独立的微服务,而流程类业务功能上升到前台类应用也作为独立的微服务。
图片来源网络
当然在这个过程中可以多参考些业务系统的功能架构图,多对比分析,然后再结合企业实际的业务需求和业务流程情况进行整合。
以数据架构分析入手划分微服务
数据驱动入手,简单来说就是一开始要弱化进行全面的业务流程分析,就是你不需要进行全面的流程分析就能够快速的构建识别和定义业务中台。
对于业务对象,我们可以初步分为两个类型
- 基础数据:其中包括了我们常说的主数据,也包括了数据字典类元数据
- 业务表单:业务表单类数据,即在业务流程工程中流转的业务表单对象数据
在我们看常见的中台架构图的时候,我们都会注意到中台的各个模板一般都会以中心来命名,比如说用户中心,产品中心,订单中心,商品中心等。而这里面出现的就是各个核心共享业务对象或数据对象。而我们要做的就是把这些关键的数据对象或业务对象识别出来。
如何识别?
我们可以调研企业各个业务部门有哪些常见的业务表单或电子表单,然后对这些表单数据进行定义。
即你关注的不是流程,而是最终的结果数据。比如我们说人力资源部门,你会看到存在请假单,用章申请单,工资条,培训需求表,培训考勤表等,这些就是最终的业务表单或数据对象。
我们可能不会去详细的分析培训组织流程,但是我们会关心培训会产生哪些业务对象数据。当然,很多时候你必须仍然要了解业务才能够识别出业务对象,只是不需要对业务流程做详细流程分析。
数据域划分-基础主数据-》共享数据-》附属数据
数据架构里面有一个重点就是数据域划分,而数据域的划分往往是我们参考进行拆库的一个重点,因此如何划分数据域成为一个关键点。当然最基本的仍然是数据之间的高内聚和低耦合性。
首先是识别和定义主数据
对于数据域的划分,我们首先还是考虑先识别和定义主数据,先将主数据识别出来,然后对主数据再进行一次数据域划分,具体仍然可以参考供应链,财务,人力资源等核心业务域进一步细划分数据域。在这里注意不一定按照互联网的做法每个关键对象就划分为一个中台模块,比如用户中心,商品中心等,而是可以按业务域划分为不同的中台模块,核心原因还是考虑数据的耦合性。
其次,我们要寻找核心动态数据,其中核心动态数据我们理解为两个关键特点
- 其一:仍然是跨多个业务域或业务流程共享
- 其二:是最终态数据,而非过程态数据
对于第二点我解释下,最终态数据即为你可能走了很多业务流程,最终形成的正式生效的数据,类似合同,订单,库存信息等,这些都是最终态数据。当然并不是说类似采购申请单,入库单,出库单这些数据不重要,而是我们首先要找到最终态数据。
我们可以看到大部分的业务流程,不论是业务流还是人工审批流最终的目标刚好就是形成正式生效的终态数据对象。而这些数据对象在内容形成后又将能力暴露出来给外部其他业务流程或业务功能使用。
按这个概念来说,对于我们做报账系统的差旅报销申请单,借款申请单也不属于最终态数据,因为这些申请单走完流程后最终的目标是形成各类凭证信息。
因此我们找寻到终态数据,基于这些来构建中台模块,类似订单中心,合同中心,库存中心就属于这类情况。
最后一个,即附属数据,也可以理解为流程中的申请单据数据,这些数据是否放到中台需要根据我们实际情况来看,具体的原则主要包括两点。
- 其一:这些附属单据数据是否和核心共享数据依赖密切,为形成核心共享数据的唯一入口来源
- 其二:我们构建中台是否要纯粹为只提供服务能力,而不提供业务功能
在上面一篇文章中我就提到了,我们构建的中台模块可以有多种呈现方式,有一种中台就是完全是逻辑层+服务提供没有任何业务功能(只保留系统管理员维护数据功能)。还有一种中台就是既提供服务能力,也提供业务功能。
那么如果要彻底按分层思路构建中台,这个时候附属数据不用划到中台中心里面,反之则可以划入。这个时候的中台既提供业务功能也提供能力服务。
比如对于订单中心,我们可以将采购订单申请,审批流程也划入到订单中心里面,这样订单中心既提供订单能力服务,也提供订单业务功能。你也可以订单中心只提供订单能力服务(包括订单导入,查询,变更等),而将其他业务功能全部划分到前台去。
可以看到,对于互联网中台构建往往是后者,而对于企业中台构建建议采用前者兼顾两个方面。