01.领域驱动设计:微服务设计为什么要选择DDD学习总结
目录
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可以给你带来以下收获:
-
DDD是一套完整而系统的设计方法,它能带给你从战略设计到战术设计的标准设计过程,使得你的设计思路能够更加清晰,设计过程更加规范。
-
DDD善于处理与领域相关的拥有高复杂度业务的产品开发,通过它可以建立一个核心而稳定的领域模型,有利于领域知识的传递与传承。
-
DDD强调团队与领域专家的合作,能够帮助你的团队建立一个沟通良好的氛围,构建一致的架构体系。
-
DDD的设计思想、原则与模式有助于提高你的架构设计能力。
-
无论是在新项目中设计微服务,还是将系统从单体架构演进到微服务,都可以遵循DDD的架构原则。
-
DDD不仅适用于微服务,也适用于传统的单体应用。
相关文章:

01.领域驱动设计:微服务设计为什么要选择DDD学习总结
目录 1、前言 2、软件架构模式的演进 3、微服务设计和拆分的困境 4、为什么 DDD适合微服务 5、DDD与微服务的关系 6、总结 1、前言 我们知道,微服务设计过程中往往会面临边界如何划定的问题,不同的人会根据自己对微服务的理 解而拆分出不同的微服…...

写静态页面——魅族导航_前端页面练习
0、效果: 1、html代码:: <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><…...

Go 命令行解析 flag 包之快速上手
本篇文章是 Go 标准库 flag 包的快速上手篇。 概述 开发一个命令行工具,视复杂程度,一般要选择一个合适的命令行解析库,简单的需求用 Go 标准库 flag 就够了,flag 的使用非常简单。 当然,除了标准库 flag 外&#x…...

React16源码: React中commitAllHostEffects内部的commitDeletion的源码实现
commitDeletion 1 )概述 在 react commit 阶段的 commitRoot 第二个while循环中调用了 commitAllHostEffects,这个函数不仅仅处理了新增节点,更新节点最后一个操作,就是删除节点,就需要调用 commitDeletion࿰…...

[机器学习]简单线性回归——梯度下降法
一.梯度下降法概念 2.代码实现 # 0. 引入依赖 import numpy as np import matplotlib.pyplot as plt# 1. 导入数据(data.csv) points np.genfromtxt(data.csv, delimiter,) points[0,0]# 提取points中的两列数据,分别作为x,y …...

2024年搭建幻兽帕鲁服务器价格多少?如何自建Palworld?
自建幻兽帕鲁服务器租用价格表,2024阿里云推出专属幻兽帕鲁Palworld游戏优惠服务器,配置分为4核16G和4核32G服务器,4核16G配置32.25元/1个月、3M带宽96.75元/1个月、8核32G配置10M带宽90.60元/1个月,8核32G配置3个月271.80元。ECS…...

『OpenCV-Python|鼠标作画笔』
Opencv-Python教程链接:https://opencv-python-tutorials.readthedocs.io/ 本文主要介绍OpenCV-Python如何将鼠标作画笔绘制圆或者矩形。 示例一:图片上双击的位置绘制一个圆圈 首先创建一个鼠标事件回调函数,鼠标事件发生时就会被执行。鼠标…...

关于如何利用ChatGPT提高编程效率的
自从去年ChatGPT3.5推出以后,这一年时间在编程过程中我也在慢慢熟悉人工智能的使用,目前来看即使是免费的ChatGPT3.5对于编程效率的提升也是有很大帮助的,虽然在使用过程中确实出现了一些问题,本文记录下我的一些心得体会和用法。…...
Excel VBA ——从MySQL数据库中导出一个报表-笔记
本文主要涉及: VBA中数据库连接参数改成从配置文件获取 VBA连接MySQL数据库 VBA读MySQL数据库 演示两种写入工作簿的代码实现系统环境: Windows 10 64bit Excel 365 64bit WAMP(3.2.2.2 64bit)集成的MariaDB版本为10.4.10&#…...

金融OCR领域实习日志(一)——OCR技术从0到1全面调研
一、OCR基础 任务要求: 工作原理 OCR(Optical Character Recognition,光学字符识别)是指电子设备(例如扫描仪或数码相)检查纸上打印的字符,经过检测暗、亮的模式肯定其形状,而后用…...

ELK日志解决方案
ELK日志解决方案 ELK套件日志系统应该是Elasticsearch使用最广泛的场景之一了,Elasticsearch支持海量数据的存储和查询,特别适合日志搜索场景。广泛使用的ELK套件(Elasticsearch、Logstash、Kibana)是日志系统最经典的案例,使用Logstash和Be…...
嵌入式学习-驱动
嵌入式的一些基本概念 CPU与MCU的区别 CPU(中央处理器,central processing unit) 指集成了运算器、控制器、寄存器、高速缓存等功能模块的芯片,负责执行计算机程序指令的处理器。MCU(单片微型计算机或单片机,microco…...

系统架构17 - 软件工程(5)
软件工程 软件测试测试原则测试方法静态测试动态测试黑盒测试白盒测试灰盒测试自动化测试 测试阶段单元测试集成测试系统测试性能测试验收测试其它测试AB测试Web测试链接测试表单测试 测试用例设计黑盒测试用例白盒测试用例 调试 系统维护遗留系统系统转换转换方式数据转换与迁…...

空气质量预测 | Python实现基于线性回归、Lasso回归、岭回归、决策树回归的空气质量预测模型
文章目录 效果一览文章概述源码设计参考资料效果一览 文章概述 政府机构使用空气质量指数 (AQI) 向公众传达当前空气污染程度或预测空气污染程度。 随着 AQI 的上升,公共卫生风险也会增加。 不同国家有自己的空气质量指数,对应不同国家的空气质量标准。 对于空气质量预测,…...

MYSQL数据库基本操作-DQL-基本查询
一.概念 数据库管理系统一个重要功能就是数据查询。数据查询不应是简单返回数据库中存储的数据,还应该根据需要对数据进行筛选以及确定数据以什么样的格式显示。 MySQL提供了功能强大,灵活的语句来实现这些操作。 MySQL数据库使用select语句来查询数据…...

gdb 调试 - 在vscode图形化展示在远程的gdb debug过程
前言 本地机器的操作系统是windows,远程机器的操作系统是linux,开发在远程机器完成,本地只能通过ssh登录到远程。现在目的是要在本地进行图形化展示在远程的gdb debug过程。(注意这并不是gdb remote !!&am…...

Android 13.0 SystemUI下拉状态栏定制二 锁屏页面横竖屏时钟都居中功能实现二
1.前言 在13.0的系统rom定制化开发中,在关于systemui的锁屏页面功能定制中,由于在平板横屏锁屏功能中,时钟显示的很大,并且是在左旁边居中显示的, 由于需要和竖屏显示一样,所以就需要用到小时钟显示,然后同样需要居中,所以就来分析下相关的源码,来实现具体的功能 如图…...

docker 部署xxl-job
docker 部署xxl-job XXL-JOB github地址 https://github.com/xuxueli/xxl-job XXL-JOB 文档地址 https://www.xuxueli.com/xxl-job/ XXL-JOB是一个分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品…...

Kafka(九)跨集群数据镜像
目录 1 跨集群镜像的应用场景1.1 区域集群和中心集群1.2 高可用(HA)和灾备(DR)1.3 监管与合规1.4 云迁移1.5 聚合边缘集群的数据 2 多集群架构2.1 星型架构2.2 双活架构2.2 主备架构2.2.1 如何实现Kafka集群的故障转移2.2.1.1 故障转移包括的内容1. 灾难恢复计划2. 非计划内的故…...
第3讲 谈谈final、finally、 finalize有什么不同?
参考 三者区别 final final 是 java 关键字可修饰变量(类成员变量、类静态变量、局部变量和形参):表示不可修改当前变量的值(这里的值可以是地址,也可以是基本类型的值)#(注意:fi…...

《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...

Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...

LabVIEW双光子成像系统技术
双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制,展现出显著的技术优势: 深层组织穿透能力:适用于活体组织深度成像 高分辨率观测性能:满足微观结构的精细研究需求 低光毒性特点:减少对样本的损伤…...
为什么要创建 Vue 实例
核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...
tomcat指定使用的jdk版本
说明 有时候需要对tomcat配置指定的jdk版本号,此时,我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...
Spring Security 认证流程——补充
一、认证流程概述 Spring Security 的认证流程基于 过滤器链(Filter Chain),核心组件包括 UsernamePasswordAuthenticationFilter、AuthenticationManager、UserDetailsService 等。整个流程可分为以下步骤: 用户提交登录请求拦…...