绪论

传统数字化转型需要解决的几个问题

1.技术体系落后

可扩展能力不强,高可用能力不强,面对突发高频访问的业务场景,不能实现自动弹性伸缩,发展到一定规模后,数据库性能和容量成为业务发展的瓶颈。

2.单体架构问题

将很多功能放到一个应用中,日积月累,这个应用编程一个庞大的怪物,随着人员的更替,时间一长很少人能完全搞懂这些代码的逻辑关系。一些人担心遗留代码,不敢修改之前的代码,宁愿复制一份代码出来重新修改,导致应用越来越复杂,最终陷入恶性循环。单体也存在模块耦合度高,弹性扩容资源利用不高。

3.研发和运维能力落后的问题

云平台和自动化运维工具对单体应用的生态支撑有限,部署和运维相对复杂,应用出现问题基本靠人肉排查,运维和研发难以快速定位。

4.IT能力重复建设问题

传统企业已经建立了一套单体核心系统,为了在移动互联网开拓业务,又建立了一套移动互联网应用,出现了一些业务同质化问题。为了解决这个问题就需要提升技术能力和重构业务模型入手,实现企业级业务的能力复用。

微服务虽好,但它只是手段不是目的,微服务是为了解决业务和应用扩展能力,也是了更好上云。微服务实施需要一定的前置条件。技术能力提升了,传统应用和移动应用才有统一的基础;应用统一了,才会有业务模型的统一;业务模型统一了,才能实现业务能力共享和复用,企业才会有实施中台战略的技术基础。

为什么会面临单体架构问题?


  1. 团队小的时候,单体的开发效率最高
  2. 当时团队技术能力不足,研发人员不够重视
  3. 服务器经费不足
  4. 业务发展不允许,业务上需要快速的实现功能,没有过多的时间去设计系统的扩展性和高可用等。

所以单体架构可能是很多团队不得不面临的一个问题,当企业发展后,单体向微服务的迁移也是一个不得不面临的问题。

认识中台

ThoughtWorks对中台的定义:“中台是企业级能力复用平台”。中台本质上是企业的业务模型。中台如何落地,微服务架构是目前公认的最佳实践,中台落地时会面临微服务应该如何拆分和设计的问题。是否有好的方法来指导微服务的拆分和设计呢?那就是DDD(领域驱动设计),DDD包含战略设计和战术设计两个阶段,通过战略设计完成中台业务边界划分和领域建模,然后将领域模型作为战术设计的输入,完成微服务设计。

阿里对前台、中台、后台职责的定位,前台主要面向客户以及终端销售者,实现营销推广以及交易转换。中台主要面向运营人员,完成运营支撑,实现不同业务板块能力的融合,形成强大的组合打击能力完成精确打击,获得最大企业效能。而数据中台就是信息情报中心和联合作战总指挥,是企业智能化的大脑,它能够汇聚各类一线作战板块的数据和信息完成数据分析,制定战略和战术计划,完成不同业务中台能力的智能调度和组合。后台就是后勤部队,主要提供企业后端支持和管理能力。

中台能力总体框架



《中台架构与实现 DDD和微服务》核心思想_数据



DDD包括战略设计和战术设计两部分,它们分别从不同的视角出发,完成领域建模和微服务的拆分和设计。战略设计是从业务视角出发,划分业务的领域边界,建立基于通用语言和业务上下文语义边界的界限上下文,构建领域模型。而界限上下文就可以作为微服务拆分和设计的边界。

战术设计则是从技术视角出发,侧重于对领域模型的技术实现,按照领域模型完成微服务的开发和落地。在战术设计上会有聚合、聚合根、实体、值对象、领域服务、领域时间、应用服务、仓储等领域对象,这些领域对象会以代码的形式映射到微服务中,完成设计和系统落地。



《中台架构与实现 DDD和微服务》核心思想_数据_02



DDD战略设计中的领域建模是一个从发散到收敛的过程,通常采用事件风暴工作法。事件风暴是一项团队活动,领域专家与项目团队通过头脑风暴的形式,罗列出领域中所有的领域事件,然后为每一个事件标注出导致该事件的命令,再为每一个事件标注出命令发起方的角色

基于事件风暴的领域建模的关键过程包括:产品愿景分析(可选)、场景分析、领域建模、微服务拆分与设计这几个重要阶段。原则上,一个界限上下文内的领域模型就可以设计为一个微服务,但领域建模时,只考虑了业务因素,并没有考虑微服务落地的技术、团队、运行环境等非业务因素,因此它只能作为微服务拆分的一个非常重要的依据,而不是唯一依据。构建边界清晰的领域模型,才是我们的最关键目标。

DDD的核心目的是为“高内聚,低耦合”提供一个可行办法。

DDD、中台、微服务的关系


《中台架构与实现 DDD和微服务》核心思想_微服务_03


这里有个设计经验,在设计过程中我们可以用一些表格来记录事件风暴和微服务设计过程中产生的领域对象与属性


需要强调一次:DDD分析和设计过程中的每个环节,都需要保证界限上下文内通用语言的统一和正确性。在代码模型设计的时候要建立领域对象和代码对象的一一映射,从而保证业务模型和系统模型一致,实现业务语言和代码语言的统一。

子域和界限上下文的关系?大多数情况下是一对一或一对多的映射关系。有时候业务领域非常庞大,不太方便使用时间风暴对整个领域构建领域模型,所以在领域建模前,我们先根据业务流程边界或功能集合等要素,将庞大领域分解为若干个合适的子域,然后在根据属性划分为核心子域、通用子域、支撑子域,然后再对这些子域内开展事件风暴,划分界限上下文

实体和值对象

在代码模型中,实体的表现形式是实体类,这个类包含了实体的属性和方法,通过这些方法实现实体自身的业务行为和业务逻辑,这些实体通常采用充血模型,跨多个实体的领域逻辑则在领域服务中实现。贫血模型中领域对象大多只有setter和getter方法,业务逻辑统一放在业务逻辑层实现,而不是领域对象中实现。

实体以领域对象(DO)的形式存在,每个实体对象都有唯一的ID,我们可以对一个实体对象多次修改,修改后的实体数据和原来的数据可能会不大相同,但是由于拥有相同的ID,他们仍然是一个实体。比如商品是商品界限上下文的一个实体,通过唯一的商品ID来标示。不管这个商品的数据如何变化,商品的ID一直保持不变,所以它始终是同一个商品。

实体的数据库形态,与传统数据库模型设计优先不同,DDD是先构建领域模型,通过场景分析找出实体对象和行为,再将实体对象映射到数据持久对象。一个实体可以对应0个、1个或多个数据库持久化对象。如何解决一对多或多对一场景?

值对象本质是个属性集合,是不可变的,它没有ID,它只是有数据初始化操作和有限的不涉及修改数据的行为,基本不包含业务逻辑。