DDD与微服务架构浅析
一、软件技术架构的演进 我们都知道这些年随着设备以及技术的发展,软件架构发生了很多变化,从最初的单机(BS/CS)架构到后面的集中式架构,再到如今的微服务架构, 现在基本可以说是微服务架构盛行的时代, DDD早在2004年就由埃里克·埃文斯提出, 但一直处于一个不愠不火的状态,直到Martin Fowler的《Microservices》引起大家注意, 也就是微服务盛行之后, DDD再次回到人们视野中间,为什么呢 ?我们先看一下三种技术架构的演进以及主要区别:
- 单机架构:
面向过程的设计方法、包括客户端UI和数据库两层,特征是整个开发围绕着数据库进行设计和开发。
- 集中式架构:
采用面向对象的设计方法,包括业务的接入层、业务逻辑层、数据访问层,这种架构很容易某一层或者几层变得臃肿,扩展性较差, 另外摩尔定律失效, 单台机器性能有限。
- 微服务架构:
微服务架构可以很好的实现应用直接的解耦,解决单体应用扩展性和弹性伸缩能力不足的问题。在集中式架构中, 系统分析、设计和开发往往是独立进行的,而且各个阶段负责人可能不一样,那么就涉及到交流信息丢失的问题, 另外项目从分析到开发经历的流程很长,很容易最终开发设计与需求实现的不一样,微服务主要就是解决第二阶段的这些痛点,实现应用之间的解耦,解决单体应用扩展性的问题。二、微服务设计和拆分的困境 进入微服务之后 , 解决了集中式架构的单体应用很多问题, 但是新的问题应运而生 , 微服务的粒度应该多大 ?微服务如何设计呢?微服务如何拆分 ?微服务边界在哪里 ?
你在技术圈中一定听说过一些项目因为前期微服务拆分过度,导致项目复杂度过高,无法上线和运维。 很长时间人们都没有解决这一问题,就连Martin Fowler在提出微服务架构的时候也没有告诉我们这该如何拆分微服务。 甚至在很长的时间里人们对微服务拆分产生了一些误解, 有人认为:”微服务很简单,就是将之前的单体应用拆分成多个部署包, 或者将原来的单体应用架构替换为一套支持微服务的技术架构,就算是微服务了。” 还有人认为微服务应该拆分得越小越好。 鉴于上述情形, 很多项目因为前期拆分过度, 导致复杂度过高, 导致后期难以运维甚至难以上线。 可以得出一个结论:微服务拆分困境产生的根本原因就是不知道业务或者微服务的边界到底在什么地方。换句话说,确定了业务边界和应用边界,这个困境也就迎刃而解了。
三、DDD核心思想
- 通过领域驱动设计方法定义领域模型,从而确定业务和应用边界,保证业务模型与代码模型的一致性。
- 有些熟悉 DDD 设计方法的软件工程师在进行微服务设计时,发现可以利用 DDD 设计方法来建立领域模型,划分领域边界,再根据这些领域边界从业务视角来划分微服务边界。
- 而按照 DDD 方法设计出的微服务的业务和应用边界都非常合理,可以很好地实现微服务内部和外部的“高内聚、低耦合”。于是越来越多的人开始把 DDD 作为微服务设计的指导思想。
四、为什么DDD适合微服务?
- DDD是处理高度复杂领域的设计思想;
- 试图分离技术实现的复杂性、并围绕业务概念构建领域模型来控制业务的复杂性、以解决软件难以理解,难以演进的问题;
- DDD不是架构、而是一种架构设计的方法论,通过边界划分将复杂的业务领域简单化、帮我们设计出清晰的领域和应用边界,可以很容易地实现架构的演进。
五、DDD的基本概念
DDD的核心思想主要包括两部分,战略设计部分和战术设计部分:
1、战略设计主要从业务视角出发,建立业务领域模型,划分领域边界,建立通用语言的限界上下文,限界上下文可以作为微服务设计的参考边界。
2、战术设计则从技术视角出发,侧重于领域模型的技术实现,完成软件开发和落地,包括:聚合根、实体、值对象、领域服务、应用服务和资源库等代码逻辑的设计和实现。
DDD****相关术语介绍:
领域模型:
DDD 战略设计会建立领域模型,领域模型可以用于指导微服务的设计和拆分;
事件风暴:
是建立领域模型的主要方法,它是一个从发散到收敛的过程,通常采用用例分析、场景分析和用户旅程分析、尽可能全面不遗留地分解业务领域、并梳理对象之间的关系,这个叫做发散的过程;事件风暴过程会产生很多实例、命令、事件等领域对象,我们将这些领域的对象从不同的维度进行聚类、形成聚合、建立领域模型,这叫收敛的过程。
限定上下文:
为了避免同样的概念或语义在不同的上下文环境中产生歧义,DDD 在战略设计上提出了“限界上下文”这个概念,用来确定语义所在的领域边界。用来封装通用语言和领域对象,提供上下文环境,保证在领域之内的一些术语、业务相关对象等(通用语言)有一个确切的含义,没有二义性。
实体:
在 DDD 中有这样一类对象,它们拥有唯一标识符,且标识符在历经各种状态变更后仍能保持一致;
值对象:
值对象的定义:通过对象属性值来识别的对象,它将多个相关属性组合为一个概念整体,值对象本是就是一个集合。
聚合:
领域模型内的实体和值对象就好比个体,而能让实体和值对象协同工作的组织就是聚合,它用来确保这些领域对象在实现共同的业务逻辑时,能保证数据的一致性。聚合就是由业务和逻辑紧密关联的实体和值对象组合而成的,聚合是数据修改和持久化的基本单元,每一个聚合对应一个仓储,实现数据的持久化。聚合有一个聚合根和上下文边界,这个边界根据业务单一职责和高内聚原则,定义了聚合内部应该包含哪些实体和值对象,而聚合之间的边界是松耦合的;
聚合根:
聚合根的主要目的是为了避免由于复杂数据模型缺少统一的业务规则控制,而导致聚合、实体之间数据不一致性的问题;如果把聚合比作组织,那聚合根就是这个组织的负责人。聚合根也称为根实体,它不仅是实体,还是聚合的管理者;在聚合内部负责协调实体和值对象按照固定的业务规则协同完成共同的业务逻辑。
六、DDD和微服务之间的关系
上面我们学习了DDD相关的思想和专业术语,下面主要讨论一下DDD与微服务之间存在的关系。
领域的核心思想就是将问题域逐级细分,来降低业务理解和系统实现的复杂度。通过领域细分,逐步缩小微服务需要解决的问题域,构建合适的领域模型,而领域模型映射成系统就是微服务了。核心域、支撑域和通用域的主要目标是:通过领域划分,区分不同子域在公司内的不同功能属性和重要性,从而公司可对不同子域采取不同的资源投入和建设策略,其关注度也会不一样。
可以从三步来划定领域模型和微服务的边界:
1、在事件风暴中梳理业务过程中的用户操作,事件以及外部依赖的关系、根据这些要素梳理出领域实体等领域对象;
2、根据领域实体之前的业务关联性,将业务紧密相关的实体进行组合形成聚合,同时确定聚合中的聚合根、值对象和实体根;
3、根据业务及语义边界等因素,将一个或者多个聚合划定在一个限界上下文内,形成领域模型。
最后梳理一下DDD与微服务的关系,DDD是一种架构设计方法,微服务是一种架构风格两者从本质上都是为了追求高响应力,而从业务视角去分离应用系统建设复杂度的手段。两者都强调从业务出发,其核心要义是强调根据业务发展,合理划分领域边界,持续调整现有架构,优化现有代码,以保持架构和代码的生命力,也就是我们常说的演进式架构。
- DDD 主要关注:从业务领域视角划分领域边界,构建通用语言进行高效沟通,通过业务抽象,建立领域模型,维持业务和代码的逻辑一致性。
- 微服务主要关注:运行时的进程间通信、容错和故障隔离,实现去中心化数据管理和去中心化服务治理,关注微服务的独立开发、测试、构建和部署。
写在最后
代码精选(www.codehuber.com),程序员的终身学习网站已上线!
如果这篇【文章】有帮助到你,希望可以给【JavaGPT】点个赞👍,创作不易,如果有对【后端技术】、【前端领域】感兴趣的小可爱,也欢迎关注❤️❤️❤️ 【JavaGPT】❤️❤️❤️,我将会给你带来巨大的【收获与惊喜】💝💝💝!
本文由博客一文多发平台 OpenWrite 发布!