01、领域驱动设计:微服务设计为什么要选择DDD总结

news2024/12/25 9:23:09

目录

1、前言

2、软件架构模式的演进

3、微服务设计和拆分的困境

4、为什么 DDD适合微服务

5、DDD与微服务的关系

6、总结


1、前言

我们知道,微服务设计过程中往往会面临边界如何划定的问题,不同的人会根据自己对微服务的理

解而拆分出不同的微服务,于是大家各执一词,谁也说服不了谁,都觉得自己很有道理。

那在实际落地过程中,见过不少项目在面临这种微服务设计困惑时,是靠拍脑袋硬完成的,上线后

运维的压力就可想而知了。那是否有合适的理论或设计方法来指导微服务设计呢?有的,就是

领域驱动设计(DDD)

2、软件架构模式的演进

我们知道,这些年来随着设备和新技术的发展,软件的架构模式发生了很大的变化。

软件架构模式大体来说经历了从单机、集中式到分布式微服务架构三个阶段的演进。随着分布式技术的快速兴起,我们已经进入到了微服务架构时代

我们先来分析一下,软件架构模式演进的三个阶段。

第一阶段是单机架构

采用面向过程的设计方法,系统包括客户端 UI 层和数据库两层,采用 C/S 架构模式,整个系统围绕数据库驱动设计和开发,并且总是从设计数据库和字段开始。

第二阶段是集中式架构

采用面向对象的设计方法,系统包括业务接入层、业务逻辑层和数据库层,采用经典的三层架构,也有部分应用采用传统的 SOA 架构。这种架构容易使系统变得臃肿,可扩展性和弹性伸缩性差。

第三阶段是分布式微服务架构

随着微服务架构理念的提出,集中式架构正向分布式微服务架构演进。微服务架构可以很好地实现应用之间的解耦,解决单体应用扩展性和弹性伸缩能力不足的问题。

我们知道,在单机和集中式架构时代系统分析、设计和开发往往是独立、分阶段割裂进行的

比如,在系统建设过程中,我们经常会看到这样的情形:A 负责提出需求,B 负责需求分析,C 负责系统设计,D负责代码实现,这样的流程很长,经手的人也很多,很容易导致信息丢失。最后,就很容易导致需求、设计与代码实现的不一致,往往到了软件上线后,我们才发现很多功能并不是自己想要的,或者做出来的功能跟自己提出的需求偏差太大。

而且在单机和集中式架构这两种模式下,软件无法快速响应需求和业务的迅速变化,最终错失发展良机。此时,分布式微服务的出现就有点恰逢其时的意思了。

3、微服务设计和拆分的困境

那进入微服务架构时代以后,微服务确实也解决了原来采用集中式架构的单体应用的很多问题,比如扩展性、弹性伸缩能力、小规模团队的敏捷开发等等。

但在看到这些好处的同时,微服务实践过程中也产生了不少的争论和疑惑:微服务的粒度应该多大呀?微服务到底应该如何拆分和设计呢?微服务的边界应该在哪里?

可以说,很久以来都没有一套系统的理论和方法可以指导微服务的拆分,包括微服务架构模式的提出者 Martin Fowler 在提出微服务架构的时候,也没有告诉我们究竟应该如何拆分微服务。

于是,在这段较长的时间里,就有不少人对微服务的理解产生了一些曲解。有人认为:“微服务很简单,不过就是把原来一个单体包拆分为多个部署包,或者将原来的单体应用架构替换为一套支持微服务架构的技术框架,就算是微服务了。” 还有人说:“微服务嘛,就是要微要小,拆得越小效果越好。”

但我想这两年,你在技术圈中一定听说过一些项目因为前期微服务拆分过度,导致项目复杂度过高,无法上线和运维。

综合来看,我认为微服务拆分困境产生的根本原因就是不知道业务或者微服务的边界到底在什么地方。换句话说,确定了业务边界和应用边界,这个困境也就迎刃而解了。

那如何确定,是否有相关理论或知识体系支持呢?在回答这些问题之前,我们先来了解一下领域驱动设计与微服务的前世今生。

2004 年埃里克·埃文斯(Eric Evans)发表了《领域驱动设计》(Domain-Driven Design–Tackling Complexity in the Heart of Software)这本书,从此领域驱动设计(DomainDriven Design,简称 DDD)诞生。DDD核心思想是通过领域驱动设计方法定义领域模型从而确定业务和应用边界,保证业务模型与代码模型的一致性

但 DDD提出后在软件开发领域一直都是“雷声大,雨点小”!直到 Martin Fowler 提出微服务架构,DDD才真正迎来了自己的时代。

有些熟悉 DDD设计方法的软件工程师在进行微服务设计时,发现可以利用 DDD设计方法来建立领域模型,划分领域边界,再根据这些领域边界从业务视角来划分微服务边界。而按照 DDD方法设计出的微服务的业务和应用边界都非常合理,可以很好地实现微服务内部和外部的“高内聚、低耦合”。于是越来越多的人开始把 DDD作为微服务设计的指导思想。

现在,很多大型互联网企业已经将 DDD设计方法作为微服务的主流设计方法了。DDD也从过去“雷声大,雨点小”,开始真正火爆起来。

4、为什么 DDD适合微服务

DDD 是一种处理高度复杂领域的设计思想,它试图分离技术实现的复杂性,并围绕业务概念构建领域模型来控制业务的复杂性,以解决软件难以理解,难以演进的问题。DDD不是架构,而是一种架构设计方法论,它通过边界划分将复杂业务领域简单化,帮我们设计出清晰的领域和应用边界,可以很容易地实现架构演进。

DDD包括战略设计战术设计两部分。

战略设计主要从业务视角出发,建立业务领域模型,划分领域边界,建立通用语言的限界上下文,限界上下文可以作为微服务设计的参考边界。

战术设计从技术视角出发侧重于领域模型的技术实现,完成软件开发和落地,包括:聚合根、实体、值对象、领域服务、应用服务和资源库代码逻辑的设计和实现。

我们来看看 DDD是如何进行战略设计的。

DDD战略设计会建立领域模型,领域模型可以用于指导微服务的设计和拆分事件风暴是建立领域模型的主要方法,它是一个从发散到收敛的过程。它通常采用用例分析、场景分析和用户旅程分析,尽可能全面不遗漏地分解业务领域,并梳理领域对象之间的关系,这是一个发散的过程。事件风暴过程会产生很多的实体、命令、事件等领域对象,我们将这些领域对象从不同的维度进行聚类,形成如聚合、限界上下文等边界,建立领域模型,这就是一个收敛的过程。

我们可以用三步来划定领域模型和微服务的边界。

第一步:在事件风暴中梳理业务过程中的用户操作、事件以及外部依赖关系等,根据这些要素梳理出领域实体等领域对象。

第二步:根据领域实体之间的业务关联性,将业务紧密相关的实体进行组合形成聚合,同时确定聚合中的聚合根、值对象和实体。在这个图里,聚合之间的边界是第一层边界,它们在同一个微服务实例中运行,这个边界是逻辑边界,所以用虚线表示。

第三步:根据业务及语义边界等因素,将一个或者多个聚合划定在一个限界上下文内,形成领域模型。在这个图里,限界上下文之间的边界是第二层边界,这一层边界可能就是未来微服务的边界,不同限界上下文内的领域逻辑被隔离在不同的微服务实例中运行,物理上相互隔离,所以是物理边界,边界之间用实线来表示。

有了这两层边界,微服务的设计就不是什么难事了。

战略设计中我们建立了领域模型,划定了业务领域的边界,建立了通用语言和限界上下文,确定了领域模型中各个领域对象的关系。到这儿,业务端领域模型的设计工作基本就完成了,这个过程同时也基本确定了应用端的微服务边界。

在从业务模型向微服务落地的过程中,也就是从战略设计向战术设计的实施过程中,我们会将领域模型中的领域对象与代码模型中的代码对象建立映射关系,将业务架构和系统架构进行绑定。当我们去响应业务变化调整业务架构和领域模型时,系统架构也会同时发生调整,并同步建立新的映射关系。

5、DDD与微服务的关系

有了上面的讲解,现在我们再次总结下 DDD与微服务的关系。

DDD是一种架构设计方法,微服务是一种架构风格,两者从本质上都是为了追求高响应力,而从业务视角去分离应用系统建设复杂度的手段。两者都强调从业务出发,其核心要义是强调根据业务发展,合理划分领域边界,持续调整现有架构,优化现有代码,以保持架构和代码的生命力,也就是我们常说的演进式架构。

DDD主要关注:从业务领域视角划分领域边界,构建通用语言进行高效沟通,通过业务抽象,建立领域模型,维持业务和代码的逻辑一致性。

微服务主要关注:运行时的进程间通信、容错和故障隔离,实现去中心化数据管理和去中心化服务治理,关注微服务的独立开发、测试、构建和部署

6、总结

今天我们主要学习微服务设计和拆分的难题。通过DDD战略设计可以建立领域模型,划定领域边界,解决微服务设计过程中,边界难以划定的难题。如果你的业务焦点在领域和领域逻辑,那么你就可以选择DDD作为微服务的设计方法!

更关键的一点是,DDD不仅可以用于微服务设计,还可以很好地应用于企业中台的设计。

如果你的企业正在做中台转型,DDD将会是一把利器,它可以帮你建立一个非常好的企业级中台业务模型。有关这点你还会在后面的文章中见到详解。

除此之外,DDD战术设计对设计和开发人员的要求相对较高,实现起来相对复杂。不同企业的研发管理能力和个人开发水平可能会存在差异。尤其对于传统企业而言,在战术设计落地的过程中,可能会存在一定挑战和困难,我建议你和你的公司如果有这方面的想法,就一定要谨慎评估自己的能力,选择最合适的方法落地DDD。

总体来说,DDD可以给你带来以下收获

  1. DDD是一套完整而系统的设计方法,它能带给你从战略设计到战术设计的标准设计过程,使得你的设计思路能够更加清晰,设计过程更加规范。

  2. DDD善于处理与领域相关的拥有高复杂度业务的产品开发,通过它可以建立一个核心而稳定的领域模型,有利于领域知识的传递与传承。

  3. DDD强调团队与领域专家的合作,能够帮助你的团队建立一个沟通良好的氛围,构建一致的架构体系。

  4. DDD的设计思想、原则与模式有助于提高你的架构设计能力

  5. 无论是在新项目中设计微服务,还是将系统从单体架构演进到微服务,都可以遵循DDD的架构原则

  6. DDD不仅适用于微服务,也适用于传统的单体应用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1408155.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

搭建《幻兽帕鲁》服务器需要怎样配置的云服务器?

随着《幻兽帕鲁》这款游戏的日益流行,越来越多的玩家希望能够在自己的服务器上体验这款游戏。然而,搭建一个稳定、高效的游戏服务器需要仔细的规划和配置。本文将分享搭建《幻兽帕鲁》服务器所需的配置及搭建步骤,助力大家获得更加畅快的游戏…

STM32 USB DFU固件升级的设计与实现

STM32微控制器支持通过USB DFU(Device Firmware Upgrade)协议进行固件升级,这使得设备可以在不需要特殊的调试工具或编程器的情况下,通过USB接口实现固件的更新。在本文中,我们将介绍如何设计和实现STM32 USB DFU固件升…

呼叫中心的管理流程

很难想象同一个客户不同时间来电购买同样的产品会得到完全不同的服务过程。许多呼叫中心都有这种“无章可循”或“有章不循”的现象,这也是导致呼叫中心低效率、高成本、高投诉的重要原因,同时也是无法建立良好客户体验的原因之一。呼叫中心流程管理的目…

yarn集群HDFS datanode无法启动问题排查

一、问题场景 hdfs无法访问,通过jps命令查看进程,发现namenode启动成功,但是所有datanode都没有启动,重启集群(start-dfs.sh)后仍然一样 二、原因分析 先看下启动的日志有无报错。打开Hadoop的日志目录 …

《WebKit 技术内幕》学习之五(3): HTML解释器和DOM 模型

3 DOM的事件机制 基于 WebKit 的浏览器事件处理过程:首先检测事件发生处的元素有无监听者,如果网页的相关节点注册了事件的监听者则浏览器会将事件派发给 WebKit 内核来处理。另外浏览器可能也需要处理这样的事件(浏览器对于有些事件必须响应…

dayjs挂载到vue3全局属性上面

首先就是安装dayjs npm install dayjs 打开main.ts //dayjs import * as dayjs from dayjs //引入插件 import * as relativeTime from dayjs/plugin/relativeTime.js import * as isLeapYear from dayjs/plugin/isLeapYear // 导入插件 import dayjs/locale/zh-cn // 导入本…

“史上最大数据泄露事件”是真还是假?

昨(2024年1月23日)天深夜,腾迅网>观点新媒体官方账号发布的《网络安全公司警告史上最大数据泄露事件 腾讯或占15亿条》这一消息,真让人闻之顿生石破惊天之感!尤其是笔者,因长期被网络假消息欺骗&#xf…

【51单片机】点亮第一个LED灯

目录 点亮第一个LED灯单片机 GPIO 介绍GPIO 概念GPIO 结构 LED简介软件设计点亮D1指示灯LED流水灯 橙色 点亮第一个LED灯 单片机 GPIO 介绍 GPIO 概念 GPIO(general purpose intput output) 是通用输入输出端口的简称, 可以通过软件来控制…

【Go面试向】defer与time.sleep初探

【Go面试向】defer与time.sleep初探 大家好 我是寸铁👊 总结了一篇defer传参与time.sleep初探的文章✨ 喜欢的小伙伴可以点点关注 💝 请大家看下面这段代码,看运行结果会出现什么,为什么? 问题 demo package mainim…

pycharm安装过程

1、安装包官网下载 PyCharm: the Python IDE for Professional Developers by JetBrains 点击下载 下拉选择社区版本 选择下载 下载完成后,双击exe安装。 安装完成,生成的桌面快捷方式 同意并继续 进入开发界面

Linux 下 TFTP 服务搭建及 U-Boot 中使用 tftp 命令实现文件下载

目录 搭建 TFTP 服务文件下载更多内容 TFTP(Trivial File Transfer Protocol,简单文件传输协议)是 TCP/IP 协议族中的一个用来在客户机与服务器之间进行简单文件传输的协议,提供不复杂、开销不大的文件传输服务,端口号…

【CANoe使用大全】——DBC数据库制作

文章目录 1.DBC数据库选择1.1.DBC模板选择1.3. 新建报文1.4. 新建信号1.5.数值表建立 2. DBC导入 1.DBC数据库选择 首先找到DBC编辑器入口 1.1.DBC模板选择 举例说明: 新建选择CANFD的模板 1.3. 新建报文 注意上图中报文周期“Cycle Time”处于不可编辑状态…

最新综述!3D Gaussian Splatting

作者:小柠檬 | 来源:3DCV 在公众号「3DCV」后台,回复「原论文」可获取论文 文章介绍了3D高斯喷洒在场景重建和渲染中的应用,并探讨了其在机器学习和计算机视觉领域的潜在应用。文章还提供了3D高斯喷洒的基本原理和优化方法&#x…

基于若依的ruoyi-nbcio流程管理系统一种简单的动态表单模拟测试实现(五)

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码: https://gitee.com/nbacheng/ruoyi-nbcio 演示地址:RuoYi-Nbcio后台管理系统 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码: https://gitee.com/nbacheng/n…

HTTP动态代理的原理及其对网络性能的影响

HTTP动态代理是一种通过代理服务器来转发HTTP请求和响应数据的网络技术,它可以优化网络性能、提高网络安全性,并解决跨域请求的问题。本文将详细介绍HTTP动态代理的原理及其对网络性能的影响。 一、HTTP动态代理的原理 HTTP动态代理的基本原理是在客户…

免费SSL申请和自动更新

当前是在mac下操作 安装certbot # mac下brew安装即可 brew install certbotcentos 安装 centos安装文档 申请泛解析证书 sudo certbot certonly --manual --preferred-challengesdns -d *.yourdomain.com## 输出 Saving debug log to /var/log/letsencrypt/letsencrypt.lo…

【Kafka】高级特性:生产者

目录 消息发送消息生产流程ProducerRecord序列化器分区器拦截器 生产者原理剖析主线程消息累加器 发送线程 生产者参数 消息发送 消息生产流程 整个流程如下: Producer创建时,会创建一个Sender线程并设置为守护线程。生产消息时,内部其实是…

幻兽帕鲁PalWorld服务器搭建详细教程

幻兽帕鲁PalWorld是一款由Pocketpair开发的游戏,融合了多种玩法,其独特的题材和画风吸引了很多玩家。为了更好地进行游戏体验,很多玩家选择自行搭建服务器。本文将详细介绍如何搭建幻兽帕鲁PalWorld服务器。 第一步:购买服务器 根…

NLP深入学习(九):KNN 算法及分类用法

文章目录 0. 引言1. 什么是 KNN2. k 值的选择3. kd 树3.1 构建 kd 树:3.2 kd 树搜索:3.3 例子 4. 参考 0. 引言 前情提要: 《NLP深入学习(一):jieba 工具包介绍》 《NLP深入学习(二&#xff09…

【C++】入门(二)

前言: c基础语法(下) 文章目录 五、引用5.1 引用概念5.2 引用使用规则5.3 常引用5.4 引用的使用场景5.5 引用和指针的区别 六、内联函数6.1 概念6.2 内联函数的特性 七、auto关键字(C11)7.1 概念7.2 使用规则7.3 用于f…