DDD学习笔记 - 进阶篇(Ⅱ)

 

09 | 中台:数字转型后到底应该共享什么?

课程链接:https://time.geekbang.org/column/article/159580

 

中台是数字化转型的一个热门话题。继阿里提出中台概念后,很多人又提出了各种各样的中台。今天主要讨论业务中台和数据中台。作为企业数字化中台转型的整体,我也会顺带聊一聊前台和后台的一些设计思路。

中台源于平台,但它的战略高度要比平台高很多。

 

平台到底是不是中台?

平台只是将部分通用的公共能力独立为共享平台。虽然可以通过 API 或者数据对外提供公共共享服务,解决系统重复建设的问题,但这类平台并没有和企业内的其它平台或应用,实现页面、业务流程和数据从前端到后端的全面融合,并且没有将核心业务服务链路作为一个整体方案考虑,各平台仍然是分离且独立的。平台解决了公共能力复用的问题,但离中台的目标显然还有一段差距!

 

中台到底是什么?

“一千个读者就有一千个哈姆雷特”。

阿里自己人对中台的定义:“中台是一个基础的理念和架构,我们要把所有的基础服务用中台的思路建设,进行联通,共同支持上端的业务。业务中台更多的是支持在线业务,数据中台提供了基础数据处理能力和很多的数据产品给所有业务方去用。业务中台、数据中台、算法中台等等一起提供对上层业务的支撑。”

思特沃克对中台的定义:“中台是企业级能力复用平台。”

可以提炼出几个关于中台的关键词:共享、联通、融合和创新。联通是前台以及中台之间的联通,融合是前台流程和数据的融合,并以共享的方式支持前端一线业务的发展和创新。

中台首先体现的是一种企业级的能力,它提供的是一套企业级的整体解决方案,解决小到企业、集团,大到生态圈的能力共享、联通和融合问题,支持业务和商业模式创新。通过平台联通和数据融合为用户提供一致的体验,更敏捷地支撑前台一线业务。中台来源于平台,但中台和平台相比,它更多体现的是一种理念的转变,它主要体现在这三个关键能力上:对前台业务的快速响应能力;企业级复用能力;从前台、中台到后台的设计、研发、页面操作、流程服务和数据的无缝联通、融合能力。其中最关键的是快速响应能力和企业级的无缝联通和融合能力,尤其是对于跨业经营的超大型企业来说至关重要。

 

数字化转型中台应该共享什么?

相对互联网企业而言,传统企业的渠道应用更多样化,有面向内部人员的门店类应用、面向外部用户的互联网电商以及移动 APP 类应用。这些应用面向的用户和场景可能不同,但其功能类似,基本涵盖了核心业务能力。此外,传统企业也会将部分核心应用的页面或 API 服务能力开放给生态圈第三方,相互借力发展。

为了适应不同业务和渠道的发展,过去很多企业的做法是开发很多独立的应用或 APP。但由于 IT 系统建设初期并没有企业级的整体规划,平台之间融合不好,就导致了用户体验不好,最关键的是用户并不想装那么多 APP。

为了提升用户体验,实现统一运营,很多企业开始缩减 APP 的数量,开始通过一个 APP 集成企业内的所有能力,联通前台所有的核心业务链路。由于传统企业的商业模式和 IT 系统建设发展的历程与互联网企业不是完全一样的,因此传统企业的中台建设策略与阿里中台战略也应该有所差异,需要共享的内容也不一样。

由于渠道多样化,传统企业不仅要将通用能力中台化,以实现通用能力的沉淀、共享和复用,这里的通用能力对应 DDD 的通用域或支撑域;传统企业还需要将核心能力中台化,以满足不同渠道的核心业务能力共享和复用的需求,避免传统核心和互联网不同渠道应用出现“后端双核心、前端两张皮”的问题,这里的核心能力对应 DDD 的核心域。

这就属于业务中台的范畴了,我们需要解决核心业务链路的联通和不同渠道服务共享的问题。除此之外,我们还需要解决系统微服务拆分后的数据孤岛、数据融合和业务创新等问题,这就属于数据中台的范畴了,尤其是当我们采用分布式架构以后,我们就更应该关注微服务拆分后的数据融合和共享问题了。

综上,在中台设计和规划时,我们需要整体考虑企业内前台、中台以及后台应用的协同,实现不同渠道应用的前端页面、流程和服务的共享,还有核心业务链路的联通以及前台流程和数据的融合、共享,支持业务和商业模式的创新。

 

如何实现前中后台的协同?

企业级能力往往是前中后台协同作战能力的体现。如果把业务中台比作陆军、火箭军和空军等专业军种的话,它主要发挥战术专业能力。前台就是作战部队,它需要根据前线的战场需求,对业务中台的能力进行调度,实现能力融合和效率最大化。而数据中台就是信息情报中心和联合作战总指挥部,它能够汇集各种数据、完成分析,制定战略和战术计划。后台就是后勤部队,提供技术支持。

1.前台:传统企业的早期系统有不少是基于业务领域或组织架构来建设的,每个系统都有自己的前端,相互独立,用户操作是竖井式,需要登录多个系统才能完成完整的业务流程。

中台后的前台建设要有一套综合考虑业务边界、流程和平台的整体解决方案,以实现各不同中台前端操作、流程和界面的联通、融合。不管后端有多少个中台,前端用户感受到的就是只有一个前台。

在前台设计中我们可以借鉴微前端的设计思想,在企业内不仅实现前端解耦和复用,还可以根据核心链路和业务流程,通过对微前端页面的动态组合和流程编排,实现前台业务的融合。前端页面可以很自然地融合到不同的终端和渠道应用核心业务链路中,实现前端页面、流程和功能复用。

2.中台:传统企业的核心业务大多是基于集中式架构开发的,而单体系统存在扩展性和弹性伸缩能力差的问题,因此无法适应忽高忽低的互联网业务场景。而数据类应用也多数通过 ETL 工具抽取数据实现数据建模、统计和报表分析功能,但由于数据时效和融合能力不够,再加上传统数据类应用本来就不是为前端而生的,因此难以快速响应前端一线业务。业务中台的建设可采用领域驱动设计方法,通过领域建模,将可复用的公共能力从各个单体剥离,沉淀并组合,采用微服务架构模式,建设成为可共享的通用能力中台。同样的,我们可以将核心能力用微服务架构模式,建设成为可面向不同渠道和场景的可复用的核心能力中台。 业务中台向前台、第三方和其它中台提供 API 服务,实现通用能力和核心能力的复用。

在将传统集中式单体按业务职责和能力细分为微服务,建设中台的过程中,会产生越来越多的独立部署的微服务。这样做虽然提升了应用弹性和高可用能力,但由于微服务的物理隔离,原来一些系统内的调用会变成跨微服务调用,再加上前后端分离,微服务拆分会导致数据进一步分离,增加企业级应用集成的难度。如果没有合适的设计和指导思想,处理不好前台、中台和后台的关系,将会进一步加剧前台流程和数据的孤岛化、碎片化。

数据中台的主要目标是打通数据孤岛,实现业务融合和创新,包括三大主要职能:

  • 一是完成企业全域数据的采集与存储,实现各不同业务类别中台数据的汇总和集中管理。
  • 二是按照标准的数据规范或数据模型,将数据按照不同主题域或场景进行加工和处理,形成面向不同主题和场景的数据应用,比如客户视图、代理人视图、渠道视图、机构视图等不同数据体系。
  • 三是建立业务需求驱动的数据体系,基于各个维度的数据,深度萃取数据价值,支持业务和商业模式的创新。

相应的,数据中台的建设就可分为三步走:

  • 第一步实现各中台业务数据的汇集,解决数据孤岛和初级数据共享问题。
  • 第二步实现企业级实时或非实时全维度数据的深度融合、加工和共享。
  • 第三步萃取数据价值,支持业务创新,加速从数据转换为业务价值的过程。

数据中台不仅限于分析型场景,也适用于交易型场景。它可以建立在数据仓库或数据平台之上,将数据服务化之后提供给业务系统。基于数据库日志捕获的技术,使数据的时效性大大提升,这样就可以为交易型场景提供很好的支撑。综上,数据中台主要完成数据的融合和加工,萃取数据业务价值,支持业务创新,对外提供数据共享服务。

3.后台:阿里对前台、中台和后台的定位:前台主要面向客户以及终端销售者,实现营销推广以及交易转化;中台主要面向运营人员,完成运营支撑;后台主要面向后台管理人员,实现流程审核、内部管理以及后勤支撑,比如采购、人力、财务和 OA 等系统。

那对于后台,为了实现内部的管理要求,很多人习惯性将这些管理要求嵌入到核心业务流程中。而一般来说这类内控管理需求对权限、管控规则和流程等要求都比较高,但是大部分管理人员只是参与了某个局部业务环节的审核。这类复杂的管理需求,会凭空增加不同渠道应用前台界面和核心流程的融合难度以及软件开发的复杂度。

在设计流程审核和管理类功能的时候,我们可以考虑按角色或岗位进行功能聚合,将复杂的管理需求从通用的核心业务链路中剥离,参考小程序的建设模式,通过特定程序入口嵌入前台 APP 或应用中。

管理需求从前台核心业务链路剥离后,前台应用将具有更好的通用性,它可以更加容易地实现各渠道前台界面和流程的融合。一个前台应用或 APP 可以无差别地同时面向外部互联网用户和内部业务人员,从而促进传统渠道与互联网渠道应用前台的融合。

 

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

10 | DDD、中台和微服务:他们是如何协作的?

课程链接:https://time.geekbang.org/column/article/161004

 

DDD 和微服务来源于西方,而中台诞生于中国的阿里巴巴。DDD已经出现了二十多年,中台和微服务的理念近几年才出现,提出后就非常火爆。看似风马牛不相及,实则缘分匪浅。中台是抽象出来的业务模型,微服务是业务模型的系统实现,DDD 作为方法论可以同时指导中台业务建模和微服务建设。

DDD 有两把利器,那就是它的战略设计和战术设计方法。

中台更多偏向业务模型,形成过程是业务领域不断细分的过程,过程中我们会将同类通用的业务能力进行聚合和业务重构,再根据限界上下文和业务内聚的原则建立领域模型。而 DDD 的战略设计最擅长的就是领域建模。

在中台完成领域建模后,就需要通过微服务来完成系统建设。此时,DDD 的战术设计又恰好可以与微服务的设计完美结合。可以说,中台和微服务正是 DDD 实战的最佳场景。

DDD 的本质

在研究和解决业务问题时,DDD 会按照一定的规则将业务领域进行细分到一定的程度,然后将问题范围限定在特定的边界内,并在这个边界内建立领域模型,进而用代码实现该领域模型,解决相应的业务问题。领域可分解为子域,子域可继续分为子子域,一直到你认为适合建立领域模型为止。子域还会根据自身重要性和功能属性划分为三类子域,它们分别是核心域、支撑域和通用域。

上面这张图,是保险的几个重要领域,进行了高阶的领域划分。每个企业的领域定位和职责会有些不一样,那在核心域的划分上肯定会有一定差异。因此,在做领域划分的时候,请务必结合企业战略,这恰恰也体现了 DDD 领域建模的重要性。通过领域划分和进一步的子域划分,就可以区分不同子域在企业内的功能属性和重要性,进而采取不同的资源投入和建设策略,这在企业 IT 系统的建设过程中十分重要,并且这样的划分还可以帮助企业进行中台设计。

中台的本质

中台来源于阿里的中台战略。作为前台的一线业务会更敏捷、更快速地适应瞬息万变的市场,而中台将集合整个集团的运营数据能力、产品技术能力,对各前台业务形成强力支撑。

中台的本质其实就是提炼各个业务板块的共同需求,进行业务和系统抽象,形成通用的可复用的业务模型,打造成组件化产品,供前台部门使用。前台要做什么业务,需要什么资源,可以直接找中台,不需要每次都去改动自己的底层。

DDD、中台和微服务的协作模式

更多的企业还是会聚焦在传统企业中台建设的模式,也就是将通用能力与核心能力全部中台化,以满足不同渠道核心业务能力的复用。

可以将需要共享的公共能力进行领域建模,建设可共享的通用中台。除此之外,还会将核心能力进行领域建模,建设面向不同渠道的可复用的核心中台。而这里的通用中台和核心中台都属于业务中台的范畴。

DDD 的子域分为核心域、通用域和支撑域。划分这几个子域的主要目的是为了确定战略资源的投入,一般来说战略投入的重点是核心域,因此后面我们就可以暂时不严格区分支撑域和通用域了。领域、中台以及微服务虽然属于不同层面的东西,但我们还是可以将他们分解对照,整理出来它们之间的关系。下面这张图,从 DDD 领域建模和中台建设这两个不同的视角对同一个企业的业务架构进行分析。

如果将企业内整个业务域作为一个问题域的话,企业内的所有业务就是一个领域。在进行领域细分时,从 DDD 视角来看,子域可分为核心域、通用域和支撑域。从中台建设的视角来看,业务域细分后的业务中台,可分为核心中台和通用中台。从领域功能属性和重要性对照来看,通用中台对应 DDD 的通用域和支撑域,核心中台对应 DDD 的核心域。从领域的功能范围来看,子域与中台是一致的。领域模型所在的限界上下文对应微服务。建立了这个映射关系,我们就可以用 DDD 来进行中台业务建模了。

这里还是以保险领域为例。保险域的业务中台分为两类:第一类是提供保险核心业务能力的核心中台(比如营销、承保和理赔等业务);第二类是支撑核心业务流程完成保险全流程的通用中台(比如订单、支付、客户和用户等)。根据 DDD 首先要建立通用语言的原则,在将 DDD 的方法引入中台设计时,我们要先建立中台和 DDD 的通用语言。这里的子域与中台是一致的,那我们就可以将子域统一为中台。

中台通过事件风暴可以进一步细分,最终完成业务领域建模。中台业务领域的功能不同,限界上下文的数量和大小就会不一样,领域模型也会不一样。

当完成业务建模后,就可以采用 DDD 战术设计,设计出聚合、实体、领域事件、领域服务以及应用服务等领域对象,再利用分层架构模型完成微服务的设计。这就是 DDD、中台和微服务在应用过程中的协作模式。

中台如何建模?

中台业务抽象的过程就是业务建模的过程,对应 DDD 的战略设计。系统抽象的过程就是微服务的建设过程,中台业务建模的过程:

第一步:按照业务流程(通常适用于核心域)或者功能属性、集合(通常适用于通用域或支撑域),将业务域细分为多个中台,再根据功能属性或重要性归类到核心中台或通用中台。核心中台设计时要考虑核心竞争力,通用中台要站在企业高度考虑共享和复用能力。

第二步:选取中台,根据用例、业务场景或用户旅程完成事件风暴,找出实体、聚合和限界上下文。依次进行领域分解,建立领域模型。由于不同中台独立建模,某些领域对象或功能可能会重复出现在其它领域模型中,也有可能本该是同一个聚合的领域对象或功能,却分散在其它的中台里,这样会导致领域模型不完整或者业务不内聚。这里先不要着急,这一步我们只需要初步确定主领域模型就可以了,在第三步中我们还会提炼并重组这些领域对象。

第三步:以主领域模型为基础,扫描其它中台领域模型,检查并确定是否存在重复或者需要重组的领域对象、功能,提炼并重构主领域模型,完成最终的领域模型设计。

第四步:选择其它主领域模型重复第三步,直到所有主领域模型完成比对和重构。

第五步:基于领域模型完成微服务设计,完成系统落地。

上面这张图,DDD 战略设计包括上述的第一步到第四步,主要为:业务域分解为中台,对中台归类,完成领域建模,建立中台业务模型。DDD 战术设计是第五步,领域模型映射为微服务,完成中台建设。

如果还是以保险领域为例的话,完成领域建模后,里面的数据就可以填上了。以通用中台的用户、客户和订单三个中台来做示例。客户中台提炼出了两个领域模型:客户信息和客户视图模型。用户中台提炼出了三个领域模型:用户管理、登录认证和权限模型。订单中台提炼出了订单模型。

这就是中台建模的全流程,当然看似简单的背后,若是遇上覆杂的业务总会出现各种各样的问题,不然应用起来也不会有那么多的困难。

 

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

问题总结

课程链接:https://time.geekbang.org/column/article/161888

 

问题 1:有关于领域可以划分为核心域、通用域和支撑域,以及子域和限界上下文关系的话题,还有是否有边界划分的量化标准?

在领域不断划分的过程中,领域会被细分为不同的子域,这个过程实际上是将问题范围不断缩小的过程。

“对于领域问题来说,可以理解为,对一个问题不断地划分,直到划分为我们熟悉的、能够快速处理的小问题。然后再对小问题的处理排列一个优先级。”

在领域细分到一定的范围后,就可以对这个子域进行事件风暴,为这个子域划分限界上下文,建立领域模型,然后就可以基于领域模型进行微服务设计了。

虽然 DDD 没有明确说明子域和限界上下文的关系。子域的划分是一种比较粗的领域边界的划分,它不考虑子域内的领域对象、对象之间的关系和结构。子域的划分往往按照业务阶段或者功能模块边界进行粗分,其目的就是为了能够在一个相对较小的问题空间内,比较方便地用事件风暴来梳理业务场景。

限界上下文本质上也是子域,限界上下文是在明确的子域内,用事件风暴划分出来的。它体现的是一种详细的设计过程。这个过程设计出了领域模型,明确了领域对象以及领域对象的依赖等关系,有了领域模型,就可以直接进行微服务设计了。

关于核心域、通用域和支撑域,划分这三个不同类型子域的主要目的是为了区分业务域的优先级,确定 IT 战略投入。将重要的资源投入在核心域上,确保好钢用在刀刃上。每个企业由于商业模式或者战略方向不一样,核心域会有一些差异,不要用固定的眼光看待不同企业的核心域。

核心域、通用域和支撑域都是业务领域,只不过重要性和功能属性不一样。采用的 DDD 设计方法和过程,是没有差异的。

从目前来看,还没有可以量化的领域以及限界上下文的划分标准。它主要依赖领域专家经验,以及和项目团队在事件风暴过程中不断地权衡和分析。不要奢望一次迭代就能够给复杂的业务,建立一个完美的领域模型。领域模型很多时候也需要多次迭代才能成型,它也需要不断地演进。但如果是用 DDD 设计出来的领域模型的边界和微服务内聚合的边界非常清晰的话,这个演进过程相对来说会简单很多,所需的时间成本也会很低。

 

问题 2:关于聚合设计的问题?领域层与基础层为什么要依赖倒置(DIP)?

聚合主要实现核心业务逻辑,里面有很多的领域对象,这些领域对象之间需要通过聚合根进行统一的管理,以确保数据的一致性。

在聚合设计时,我们会用到两个重要的设计模式:工厂(Factory)模式和仓储(Repository)模式。推荐阅读《实现领域驱动设计》一书的第 11 章和第 12 章。

为什么要引入工厂模式呢?因为有些聚合内可能含有非常多的实体和值对象,需要确保聚合根以及所有被依赖的对象实例同时被创建。如果都通过聚合根来构造,将会非常复杂。因此可以通过工厂模式来封装复杂对象的创建过程,但并不是所有对象的构造都需要用到工厂,如果构造过程不复杂,只是单一对象的构造,用简单的构造方法就足够了。

又为什么要引入仓储模式?解答这个问题的同时,也一起将依赖倒置的问题解答一下。在传统的 DDD 四层架构中,所有层都是依赖基础层的。这样做有什么不好的地方呢?如果应用逻辑对基础层依赖太大的话,基础层中与资源有关的代码可能会渗透到应用逻辑中。而现在技术组件的更新频率是很快的,一旦出现基础组件的变更,且基础组件的代码被带入到了应用逻辑中,这样会对上层的应用逻辑产生致命的影响。

为了解耦应用逻辑和基础资源,在基础层和上层应用逻辑之间会增加一层,这一层就是仓储层。一个聚合对应一个仓储,仓储实现聚合内数据的持久化。聚合内的应用逻辑通过接口来访问基础资源,仓储实现在基础层实现。这样应用逻辑和基础资源的实现逻辑是分离的。如果变更基础资源组件,只需要替换仓储实现就可以了,不会对应用逻辑产生太大的影响,这样就实现了应用逻辑与基础资源的解耦,也就实现了依赖倒置。

关于聚合设计过程中的一些原则问题。大部分的业务场景都可以通过事件风暴,找到聚合根,建立聚合,划分限界上下文,建立领域模型。但也有部分场景,比如数据计算、统计以及批处理业务场景,所有的实体都是独立无关联的,找不到聚合根,也无法建立领域模型。但是它们之间的业务关系是非常紧密的,在业务上是高内聚的。也可以将这类场景作为一个聚合处理,除了不考虑聚合根的设计方法外,其它诸如 DDD 分层架构相关的设计方法都是可以采用的。

一些业务场景,如果复杂度并不高,而用 DDD 设计会带来不必要的麻烦的话,比如增加复杂度,有些原则也是可以突破的,不要为做 DDD 而做 DDD。即使采用传统的方式也是没有关系的,最终以解决实际问题为最佳。但必须记住一点,如果采用传统的设计方式,一定要保证领域模型的边界以及微服务内聚合的逻辑边界清晰,这样的话,以后微服务的演进就不会太复杂。

 

问题 3:领域事件采用消息异步机制,发布方和订阅方数据如何保证一致性?微服务内聚合之间领域事件是否一定要用事件总线?

在领域事件设计中,为了解耦微服务,微服务之间数据采用最终一致性原则。由于发布方是在消息总线发布消息以后,并不关心数据是否送达,或者送达后订阅方是否正常处理,因此有些技术人会担心发布方和订阅方数据一致性的问题。

在对数据一致性要求比较高的业务场景,是有相关的设计考虑的。也就是发送方和订阅方的事件数据都必须落库,发送方除了保存业务数据以外,在往消息中间件发布消息之前,会先将要发布的消息写入本地库。而接收方在处理消息之前,需要先将收到的消息写入本地库。然后可以采用定期对发布方和订阅方的事件数据对账的操作,识别出不一致的数据。如果数据出现异常或不一致的情况,可以启动定时程序再次发送,必要时可以转人工操作处理。

关于事件总线的问题。由于微服务内的逻辑都在一个进程内,后端数据库也是一个,微服务内的事务相比微服务之间会好控制一些。在处理微服务内的领域事件时,如果引入事件总线,会增加开发的复杂度,那是否引入事件总线,需要权衡。

如果你的场景中,不会出现导致聚合之间数据不一致的情况,就可以不使用事件总线。另外,通过应用服务也可以实现聚合之间的服务和数据协调。

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章