一、中台缘起

一切源自于马云在2015年的一次欧洲之旅,当时,马云带队阿里一行高管前往北欧芬兰一家名为Supercell的游戏公司进行考察(号称是世界上最成功的移动游戏公司)。该公司里,5-7个员工就可以组成一个独立的开发团队,称之为cell。

小团队自己决定做什么样的产品,然后推出市场,观察市场反馈。反馈不好的游戏,则会被毫不犹豫地砍掉。这样的开发模式使得Supercell公司开发的游戏大获成功,而这一切成功的背后,是Supercell的强大的中台的支撑。

Supercell的中台,指的是公司将游戏开发过程中公共和通用的游戏素材和算法整合起来,并积累了非常科学的研发工具和框架体系,构建了一个功能非常强大的中台。这样强大的中台可以支持若干个小团队在短时间内开发出一款新的游戏。每一次遭遇到项目失败,Supercell全公司都会开香槟庆祝自己得到了教训和成长。

有了中台的支撑,Supercell的“细胞”才可以非常灵活地运作,形成高效的散兵作战模式。

类比美军作战模式,就可进一步感受中台的作用。美军在二战时期,以军为单位作战;越战时变成以营为单位作战;中东战争时期进化为7人或11人的极小班排作战。之所以美军的“小前端”如此灵活,因为有强大的中台能力,给前端军队提供各种资源支持以及中台炮火群支持打击。

交易中台建设_交易

二、什么是中台

玄难对于电商业务中台的定义:中台由一系列业务能力标准、运行机制、业务分析方法论,配置管理和执行系统以及运营服务团队构成的体系,提供各业务方能够快速,低成本创新的能力。

中台化是平台化的自然演进:中台解决的是多领域的复杂协同问题,重点是产品化和平台化。产品化是一种技术沉淀,闭封性优秀的系统,尽量不要外面的使用者关心我内部的实现;平台化是单领域的抽象建模,一种对外的能力,提升的是外部系统与平台系统之间的联接能力,目标是高内聚、低耦合、职责边界清晰。那么中台化架构进一步可总结为:高内聚、低耦合;数据完整性原则;业务可运营原则。

交易中台建设_交易_02

中台是一组能力的组合:

解决的是面的问题。首先我们需要一个平台容器(不是pandroa容器,而是一个逻辑容器),来管理我们的能力,其次我们需要raise我们的高度和已有的同类产品差异化掉。能力化平台真正是面向组件的设计,其次是面向点的集成。

中台是一个集成化的解决方案:

有人,有平台,有数据,有对接标准,包括组织规范和系统的规范,是人和系统的一个方法论,是一整套体系。中台是解决信息呈现,快速匹配,解决供需撮合机制。包括业务支撑、能力应用、能力管理、配置管理。中台解决的是顶级领域下各业务子域的协同问题,一般一个部门只需要一个业务中台。

中台是一种组织管理方式:

中台的管理方式是一种“去中心化”的组织架构模式,中台突出的是规划控制和协调的能力,而前台强调的是创新和灵活多变。中台突出整个设计的总体和协调性,而前端强调设计的创新和适应性,又或者说差异化。中台人要少,前台人要多。如果前台人少,中台人多,那这个中台基本上应该归属到前台。

中台不是系统或者平台:

中台是一个体系,一个生态,中台团队(比如玄难的中台运营团队)负责建立标准和机制,并提供支撑的运营管理平台和参考的实践技术框架,剩下中台的能力丰富则需要各BU、各业务域的共同建设,大家共享中台,既是中台能力的使用方,又是中台能力的提供方。

中台是一个基础的理念和架构:

我们要把所有的基础服务用中台的思路建设,进行联通,共同支持上端的业务。业务中台更多的是支持在线业务,数据中台提供了基础数据处理能力和很多的数据产品给所有业务方去用。业务中台、数据中台、算法中台等等一起提供对上层业务的支撑。不论是业务中台还是数据中台,实际上都是一个架构层面的去连接底下这部分资源

中台前的部门组织架构

交易中台建设_交易_03

- 按照上图,之前业务是业务线模式划分,每个业务线有自己的服务、产品、技术团队,业务与业务之间隔离;- 优点:业务线隔离,可以根据自己的业务节奏发展,自己团队的能力也根据自己业务特点调整;

- 缺点:业务线隔离,团队能力参差不齐,在发展新业务团队时间,能力无法复用,组成的团队无法快速磨合和使用


交易中台建设_交易_04

调整为中台战略后,团队资源根据能力进行划分,对业务进行体系的支持;- 优点:每个团队的质量、体系是一致的,团队与团队之间协调可以制定统一的协作模式;

三、为什么需要建设中台

老的协作方式的问题


交易中台建设_交易_05

交易中台建设_交易_06

交易中台建设_交易_07

中台化如何解决

交易中台建设_交易_08

中台化后的效果

交易中台建设_交易_09

四、中台如何落地

方法论

中台是抽象出来的业务模型,微服务是业务模型的系统实现,DDD 作为方法论可以同时指导中台业务建模和微服务建设,三者相辅相成,完美结合

什么是DDD?

DDD 全称是 Domain-Driven Design,中文叫领域驱动设计,2004年Eric Evans 发表Domain-Driven Design –Tackling Complexity in the Heart of Software 提出的,是一套应对复杂软件系统分析和设计的面向对象建模方法论。

以前的系统分析和设计是分开的,导致需求和成品非常容易出现偏差,两者相对独立,还会导致沟通困难,DDD 则打破了这种隔阂,提出了领域模型概念,统一了分析和设计编程,使得软件能够更灵活快速跟随需求变化。

交易中台建设_交易_10

领域与子域

领域就是Domain,在DDD中,领域主要强调的是范围,也就是边界。在研究和解决业务问题时,DDD会按照一定的规则对业务领域进行细分,当细分到一定程度后,DDD会将问题范围限定在特定的边界内,之后在边界内建立领域模型。

其实领域建模与微服务设计过程和方法是基本类似的,其核心思想就是将复杂的业务问题域逐级分解,将复杂的问题简单化。

领域经过不断的划分就会形成不同的子域,子域可以根据重要性和功能分为核心子域、通用子域以及支撑子域。

  • 核心子域:产品中具有企业间核心竞争力的功能或者系统中的核心模块。
  • 通用子域:没有太多个性化的同时可以多个子域重复共享的通用能力子域。
  • 支撑子域:为系统或其他子域提供必要功能支撑的子域。

其实划分区域和子域的目的是为了区别不同子域在企业内的不同功能属性和重要性。个人认为没有必要过分纠结怎样明确的划分,就比如很多时候有些域即是核心子域也是通用子域,需要其通用能力实现复用,但是其也是系统中的核心模块。而且不同的子域随着业务不断的变化身份进行互换也是可能的。


以订单系统为例 :

领域,子域:

业务域: 购买域, 履约域,售后域,资金域

核心子域: 下单支付,订单退款

通用子域 :用户子域,促销子域,订单评价子域,支付子域,商家子域,库存子域

支撑子域 : 风控子域(能力) ,短信通知,企业IM通知

限界与上下文

先说说通用语言,我的理解是在团队交流中,不论担当的是什么角色,都能够简单、清晰、准确地描述业务含义和规则的语言就是通用语言。有了通用语言,团队内交流过程中就不会产生歧义,而且因为建立了领域对象与代码对象的映射关系,就可以指导开发准确无误的按照领域模型和设计文档进行开发了。

通用语言包含术语和用例场景,并且能够直接反映在代码中。通用语言中的名词可以给领域对象命名,如商品、订单等,对应实体对象;而动词则表示一个动作或事件,如商品已下单、订单已付款等,对应领域事件或者命令。

我们知道语言都有它的语义环境,同样,通用语言也有它的上下文环境。为了避免同样的概念或语义在不同的上下文环境中产生歧义,DDD 在战略设计上提出了“限界上下文”这个概念,用来确定语义所在的领域边界。这里可以将限界上下文拆解为两个词:限界和上下文。限界就是领域的边界,而上下文则是语义环境。通过领域的限界上下文,我们就可以在统一的领域边界内用统一的语言进行交流。

我们将限界上下文内的领域模型映射到微服务,就完成了从问题域到软件的解决方案。

实体与值对象

实体 Entities

实体是一个具有唯一身份标识的对象,并且可以在相当长的一段时间内持续地变化。我们可以对实体做多次修改,一个实体对象可能和它先前的对象大不相同,但拥有相同的身份标识(identity),依然是同一个实体。对这些对象而言,重要的不是其属性,而是其延续性和标识,我们把这样的对象称为实体。

四种模型定义 :

失血模型 :模型仅仅包含数据的定义和getter/setter方法,业务逻辑和应用逻辑都放到服务层中,这种类在java中叫做POJO类。

贫血模型 :贫血模型中包含了一些业务逻辑,但是不包含依赖持久层的业务逻辑,这部分会放到服务层。

充血模型 :充血模型包含了所有的业务逻辑,包括依赖于持久层的业务逻辑,不仅是多个业务属性的载体,也是操作和行为的载体。

胀血模型 : 胀血模型就是把和业务不相关的其他应用逻辑(比如授权,事务等)都放到领域模型中。可以认为是另外一种的失血模型,因为服务层service消失了,领域层干了服务层的事,到头来还是什么都没变。

DDD中的实体,通常属于充血模型

实体的数据库形态

在领域模型映射到数据模型时,一个实体可能对应 0 个、1 个或者多个数据库持久化对象。大多数情况下实体与持久化对象是一对一。在某些场景中,有些实体只是暂驻静态内存的一个运行态实体,它不需要持久化。比如,基于多个价格配置数据计算后生成的折扣实体。

而在有些复杂场景下,实体与持久化对象则可能是一对多或者多对一的关系。比如,用户 user 与角色 role 两个持久化对象可生成权限实体,一个实体对应两个持久化对象,这是一对多的场景。再比如,有些场景为了避免数据库的联表查询,提升系统性能,会将客户信息 customer 和账户信息 account 两类数据保存到同一张数据库表中,客户和账户两个实体可根据需要从一个持久化对象中生成,这就是多对一的场景

值对象 Value Object

值对象用来描述领域的特定方面,并且是一个没有标识符的对象。值对象本质上就是一个集合,这个集合中包含若干个用于描述目的、具有整体概念和不可修改的属性。它可以避免属性零碎,让属性归类更加地清晰,从概念理解上也更加完整。值对象创建后就不允许修改了,只能用另外一个值对象来整体替换。

订单系统举例 :

订单实体 :

预订单实体tradeOrderInfo,履约单实体fulfillmentOrderInfo; 售后订单refundInfo 

订单促销实体OrderItemsPandoraDiscountInfo

订单值对象 : 

订单收货地址addressInfo,订单实体可以整体引用和修改地址值对象的数据,但不允许单独修改地址值对象的某一个属性数据,如 street。所有地址数据的新增和修改等维护操作,都只能在客户聚合中完成,这样就可以实现业务职责的高内聚


聚合与聚合根

DDD中,实体与值对象是基础的领域对象。实体一般对应业务对象,具有相对丰富的业务属性与行为。值对象主要是属性集合,完成对实体的的状态和特征描述。但是实体和值对象都只是个体化的业务对象,表现出来的也是个体行为和能力。在领域模型中需要将紧密相关的个体对象组织起来进而发挥更大的价值和力量,就形成了聚合。

聚合就是由业务和逻辑紧密相关的实体和值对象组合而成的。聚合在 DDD 分层架构里属于领域层,领域层包含了多个聚合,共同实现核心业务逻辑。

在一个聚合内必须有一个聚合根,聚合根是一个实体,其存在的主要目的是避免聚合内由于复杂的数据模型缺少统一的业务规则控制,而导致聚合内实体与值对象等领域对象之间数据不一致的问题,聚合根在聚合内部负责协调实体和值对象按照固定的业务规则协同完成共同的业务逻辑。

聚合之间通过聚合根 ID 关联引用,如果需要访问其它聚合的实体,就要先访问聚合根,再导航到聚合内部实体,外部对象不能直接访问聚合内实体。


订单系统举例 :

预订单聚合: 聚合根为tradeOrderInfo实体,其他实体为orderItem, 资金池实体PayPool,

订单优惠实体OrderItemsPandoraDiscountInfo, 订单消费项实体OrderItemConsumeInfo

退款单聚合 : 聚合根为refundInfo,其他实体为 退单商品refundItem,退款分摊refundItemPandoraInfo 退款日志orderRefundLog,退款扩展实体OrderRefundExt

履约单聚合: 聚合根为履约单FulfillmentOrderInfo,其他实体为履约详情实体FulfillmentOrderItemInfo,履约金额实体 FulFillmentOrderItemAmountInfo


DDD分层架构

DDD分层架构经过不断的发展和演进,形成了现在的四层架构,四层从上至下分别是用户接口层、应用层、领域层和基础层。

交易中台建设_交易_11

DDD 中台 和 微服务 

交易中台建设_交易_12

从业务视角建立DDD与中台的统一语言

在了解了中台和DDD的问题域分解和建模的过程后,我们就可以从业务视角来建立DDD与中台的统一语言了。

一般来说,中台建设会站在企业高度,所以我们将问题空间定位在全企业的业务域。当我们从DDD的视角来进行领域分析时,我们会根据核心业务环节或者功能聚合边界以及领域经验等多个维度,完成从领域到子域的细分。并根据企业发展战略来分析,以确定子域到底是通用子域还是核心子域。

而当我们从中台建设视角出发,将不同的业务板块细分为通用中台和核心中台时,从下图中我们就可以发现,中台一般会跟DDD的某一个子域对应,所以我们可以认为:“中台本质上就是按照DDD方法从企业业务领域细分出来的某个子域”。

DDD领域模型 到中台 的转换


交易中台建设_交易_13

中台落地 在美团点评的实践

根据业务bizCode 执行不同的业务流程编排

交易中台建设_交易_14

具体落地实践

1.编写业务流程编排文件

2.设计系统接口

3.编写业务活动编排文件

4.设计方法,调用各项域服务能力,获取结果

5.根据业务 设计扩展点,并且打成插件包 


交易中台建设_交易_15


域服务,域能力和扩展点抽象举例 -- 购买域

交易中台建设_交易_16

履约域能力图

交易中台建设_交易_17

售后域能力图

交易中台建设_交易_18

流程推演 和 业务编排    

老系统  流程推演演进  新系统 如下两图示例


交易中台建设_交易_19

交易中台建设_交易_20

流程编排举例 Java DSL基本语法

交易中台建设_交易_21

交易中台建设_交易_22

交易中台建设_交易_23

并行流程

交易中台建设_交易_24

交易中台建设_交易_25

整体运行示意图

交易中台建设_交易_26

购买域举例

交易中台建设_交易_27

新老平台迁移 实施步骤

交易中台建设_交易_28

双写阶段 数据链路图

交易中台建设_交易_29

读写灰度阶段 数据链路图

交易中台建设_交易_30


阿里中台 关于TMF和星环

   TMF 是 Trade Modularization Framework 的全称,即交易模块化框架,最初是交易系统中的一个代码模块,后来剔除业务耦合部分,独立出来成为一个实现业务与平台分离的业务框架,在业务平台核心系统中广泛应用,如buy2,carts2,trademanger,tradeplatform3。目前应用如果想接入星环,提供扩展点,前提是系统进行了tmf改造。


TMF架构

交易中台建设_交易_31

TMF接入

1、确定业务身份:

  • 业务身份(tmf中的垂直业务)是tmf执行的前提,通过业务身份来实现业务和平台平台的隔离,业务和业务的隔离。业务身份的定义放到app包的tmf-plugin文件中。
  • 目前提供的业务身份解析有两种方式:1、基于lattice提供的规则脚本的方式,2、直接在app包中写BizCodeParser解析类,并定义在tmf-plugin.xml中。tmf提供了统一的业务身份解析方法,可以直接调用:String bizCode = IdentityParserClient.getInstance().parseBizCode(orderLineSpec);也可以自己实现业务身份的解析,根据当前请求能获取到唯一的业务身份code即可。

2、系统领域模型分析:

  • 系统服务:系统对外提供的服务入口,用注解@ServiceEntrance 标识。
  • 业务活动:系统流程中的活动节点,用注解@Activity 标识,该注解中的serviceCodes参数,代表该业务活动调用的域服务code,定义的时候,定义好可以关联展示。
  • 域:系统的功能域,比如订单域、库存域。用注解@Domain注解标识。
  • 域服务:指各个功能域能对外提供可供系统流程编排的服务接口。使用注解@DomainService标识
  • 域能力:具体域能力中,可以被业务方定制的子能力或者过程。举例订单域提供了下单的域服务,下单需要进行订单校验、拆单、寻仓等等,你可以把这些细分的操作理解为域能力。使用注解@Ability标识
  • 域能力扩展点:这个是参数层面的扩展点,你可以理解成为了适应不同的业务提供了一个参数转换的功能。使用注解@AbilityExtension标识
  • 商业能力:商业能力管理自身的业务流程,通过多角色协作的业务活动完成某个商业目的;是系统能力、业务活动、衡量标准的结合;商业能力本质上还是一组业务活动的聚合,商业能力的内容由对商业目的的目标用户更为了解的人来确定, 使用注解@Ability标识。
  • 商业能力扩展点:对商业能力的具体实现点,包括满足不同参数的场景
  • app业务包:业务的定制化模板,可以理解为垂直业务不能叠加,用来覆盖商业能力的扩展点方法,实现定制化功能。使用注解@TemplateExt表示
  • 产品:基于一个或多个商业能力开发,可以提供给业务方使用的软件服务。它跟app业务包的区别在于他没有业务身份。使用注解@Product标识

交易中台建设_交易_32

交易中台建设_交易_33


交易中台建设_交易_34

交易中台建设_交易_35

交易中台建设_交易_36

交易中台建设_交易_37

商业能力的定义

交易中台建设_交易_38

交易中台建设_交易_39

交易中台建设_交易_40

交易中台建设_交易_41


  • OrderBusinessDomainExt 里面的getOrderExt 做了桥接,主要方便后面OrderBusinessExt去使用商业能力

交易中台建设_交易_42

交易中台建设_交易_43

交易中台建设_交易_44

交易中台建设_交易_45

3、业务APP开发以及业务配置

  • 在app包中的tmf-plugin.xml中定义业务身份。
  • 在app包中开发扩展点的实现,实现类上用@TemplateExt注解标识。
  • tmf实现了配置域和执行域的隔离,所以系统执行还需要按照业务身份维度有一份配置文件,配置文件中主要定义该业务执行的时候,叠加了哪些产品,使用了哪些扩展点,扩展点有冲突的时候,执行顺序是啥。
  • 如果只是使用TMF重构,不使用Lattice,那么在app里面的resource目录下,每个业务身份都要有一份业务配置的xml,并在tmf-plugin中pluginClass里面进行初始化。如果使用了lattice,tmf-plugin中增加一个数据,newPlugin="1",本地无需业务配置,应用启动时,自动获取lattice推送的业务配置。

交易中台建设_交易_46

TMF执行流程如下

交易中台建设_交易_47