微服务和领域驱动

news2024/11/23 9:28:54

一、微服务

1.1 什么是微服务

微服务就是一些协同工作的小而自治的服务。

关键词: 小而自治

--

小”这个概念,一方面体现在微服务的内聚性上。

  • 内聚性也可以称之为单一职责原则:“把因相同原因而变化的东西聚合到一起,而把因不同原因而变化的东西分离开来。
  • 也就是说,微服务应该专注于做好一件事情。
  • 由业务边界来确定服务的边界

-- 自治

自治”这个概念,强调的是,一个微服务就是一个独立的实体。体现在服务之间的松耦合上。黄金法则:你是否能够修改一个服务并对其进行部署,而不影响其他任何服务?

1.2 微服务的好处

  • 技术异构性
    • 不同服务根据业务场景、性能要求、功能需求采用不同的技术架构
    • 新技术的快速实践,技术团队的快速成长
  • 弹性/反脆弱性(anti-fragility)
    • 服务降级
    • 服务容灾、服务熔断
  • 扩展
    • 传统单体系统,无法做到对局部功能进行扩展
    • 根据具体的业务需求,对特定的微服务进行扩展
    • 通过架构的手段,节省成本
  • 简化部署
    • 传统单体应用,即使是一行代码修改,也需要整体重新部署。风险太大。
    • 微服务架构,各个服务部署相互独立
    • 灵活的发版方式
    • 快速回滚
    • 风险小
  • 架构与组织结构相匹配
    • 关联知识点:康威定律
    • 服务的可重用、可组合
    • 服务的可替代性,快速重写

1. 3微服务的弊端

对运维能力要求高;运行效率会降低;技术要求高,需要处理事务最终一致性等问题。微服务不该是这样的:

二、好服务的特征

2.1松耦合

松耦合指的是,修改一个服务,而另一个相关的服务,不需要修改。微服务的重要特点就是:能够独立修改和部署单个服务,而不会影响、甚至修改系统中的其它服务。

一个服务应该尽可能少地了解与之协作的服务信息。因为过度了解,会导致紧耦合。

2.2高内聚

高内聚指的是,把相关的行为聚集在一起。这样,需要改变行为时,只需要在一处修改,然后独立发布。

我们需要做的是,找出业务领域的边界,然后实现高内聚

三、微服务拆分原则

还是要重申两个重要概念,高内聚和松耦合,对应前面的关键词:小而自治

3.1限界上下文

微服务一定要有清晰的功能边界。一个微服务对应了一个功能集合,这些功能一定是有一些共性的。比如,订单服务,那么创建订单、修改订单、查询订单列表,一般是订单服务的功能集合。

3.2逐步划分

一开始,我们会首先识别出一个粒度比较粗的服务模型。领域拆分并不是一步到位的,应当根据实际情况逐步展开。从单体应用到微服务体系的拆分过程能很好的说明这个问题。所以如果一开始不知道应该划分多细,完全可以先粗粒度划分,然后随着需要,初步拆分。比如一个电商一开始索性可以拆分为商品服务和交易服务,一个负责展示商品,一个负责购买支付。随后随着交易服务越来越复杂,就可以逐步的拆分成订单服务和支付服务。

四、DDD领域驱动设计

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

  • DDD是一个很好的应用于微服务架构的方法论;
  • 在项目的全生命周期内,所有岗位的人员都基于对业务的相同的理解来开展工作。所有人员站在用户的角度、业务的角度去思考问题,而不是站在技术的角度去思考问题;
  • 诞生于2004年,兴起于2014年(微服务元年);
  • DDD晦涩难懂,难以落地。因为DDD是方法论,不是行动指南

4.1 领域和子域

领域可以是多个子领域的一个虚拟集合,换句话说多个微服务也可以形成一个大域,不必纠结于领域和微服务之间的数量对应关系。例如在做架构设计的时候可能就把订单域作为一个领域,代表了这个域就是关于订单的,具体该有几个微服务,这需要更细的详细设计来提供。子域可以根据自身重要性和功能属性划分为三类子域,它们分别是:核心域、通用域和支撑域

4.2 界限上下文

任何领域模型都必须是在其特定的上下文环境中,如果DDD超出了其界定的上下文,则会产生歧义或者错误。例如社交媒体中的连接和网络应用中的连接的含义是完全不同的。对于任何上下文,我们都必须要能够建立明确的上下文的关联关系和边界。模型中的角色和边界的定义,在项目中非常重要。

4.3 

库(Repositories)库指的是所有拥有共同实体和值接口的服务,且这些实体和值都在同一个聚合组中。库通常应该有增加,删除,修改和查找组中对象的方法。可以直接通过应用业务逻辑查询的引用来进行简洁的查询。

4.4 通用语言

通用语言就是能够简单、清晰、准确描述业务涵义和规则的语言。通用语言是团队统一的语言,不管你在团队中承担什么角色,在同一个领域的软件生命周期里都使用统一的语言进行交流。那么,通用语言的价值也就很明了,它可以解决交流障碍这个问题

4.5 聚合和聚合根

聚合(Aggregate):用来定义领域对象所有权和边界的领域模式,是用来帮助简化模型对象间的关系。通过定义对象之间清晰的所属关系和边界来实现领域模型的内聚,并避免了错综复杂的难以维护的对象关系网的形成。

聚合根(Aggregate Root):每个聚合都有一个根对象(聚合根实体),从外部访问只能通过这个对象。根实体对象有组成聚合所有对象的引用,但是外部对象只能引用根对象实体。只有聚合根才能使用仓储库直接查询,如果根实体被删除,聚合内部的其它对象也将被删除。

4.6 实体和值对象

实体(Entity):一个由它的标识定义的对象叫做实体。通常实体具备唯一ID,能够被持久化,具有业务逻辑,对应现实世界业务对象。

值对象(Value Object):一个没有概念上标识符描述一个领域方面的对象,这些对象是用来表示临时的事物,或者可以认为值对象是实体的属性,这些属性没有特性标识但同时表达了领域中某类含义的概念。通常值对象不具有唯一ID,由对象的属性描述,可以用来传递参数或对实体进行补充描述。

4.7 领域事件

领域事件是对领域内发生的活动进行的建模。一个消息监听可以当成一个领域事件,表示发生了什么事情,然后需要做什么。领域事件对象用于记录模型产生的离散事件,我们必须谨慎选择和记录领域事件,仅仅对于那些有意义的事件进行记录。

4.8 领域和数据库

一般按垂直业务拆分,一个服务对应独立的库(也可能出现多个服务公用一个库,从设计上通常没有公用表),绝大多数情况下,一个服务和一个数据库搭配,对外提供接口。数据库应该被视为每个领域服务层微服务的私有数据库。

4.9 领域内拆分

领域拆分并不是一成不变的,应当具体情况具体分析。比如大众点评,其订单服务就拆分为了order-service和order-query-service,一来为了读写分离,二来order-query-service作为单独应用可以按需水平扩容。

4.10 核心子域、支撑子域、通用子域

-- 核心子域:

决定业务成功和公司核心竞争力的子域,整个系统最重要部分。 Eric Evans 曾提出如下问题助识别核心域:

  • 为何这系统值得写?
  • 为何不直接买个?
  • 为何不让外包写?

若你对这几个问题的回答能帮你找到这个系统非写不可的理由,则它就是核心域。如电商系统的订单、商品服务。

-- 支撑子域(Supporting Subdomain)

不是你的核心竞争力,但又得做,市场无现成方案的子域。既不包含决定产品和公司核心竞争力的功能,也不包含通用功能的子域,但又必需。

具有企业特性,但不具通用性,如:

  • 数据代码类的数据字典等系统
  • 排行榜,可能根据各种信息排名,这种东西没人会按你需要做个,但对你自己,又是扩展自己系统的重要举措
  • 调用银联、支付宝等第三方支付,即下游
  • 报表系统
  • 监控系统

-- 通用域(Generic Subdomain)

无太多个性化需求,同时会被多个子域使用的通用功能子域。如认证、权限等,无企业特点限制,无需太多定制化。行业里都这么做,即便不自己做,也不影响业务运行。

如很多 App 要给用户发通知,这种功能完全可买个服务,丝毫不影响业务运行。

五、DDD领域驱动经典四层设计

脚本式编程(dao+service)与DDD领域驱动模式区别如下:

 

5.1展现(表现层/用户接口层)(Presentation Layer):

负责以Restful的格式接受Web请求,然后将请求路由给Application层执行,并返回视图模型(View Model),其载体通常是DTO(Data Transfer Object);

5.2应用层(Application Layer):

主要负责获取输入,组装上下文,做输入校验,调用领域层做业务处理,如果需要的话,发送消息通知。当然,层次是开放的,若有需要,应用层也可以直接访问基础实施层;应用层连接用户接口层和领域层,不应该实现领域模型的核心领域逻辑。主要职能:协调领域层多个聚合完成服务的组合和编排。应用服务主要负责服务组合、编排和转发,处理业务用例的执行顺序以及结果的拼装。在应用服务中还可以进行安全认证、权限校验、事务控制、领域事件发布或订阅等。

5.3领域层(Domain Layer):

领域层是领域模型的核心,主要实现领域模型的核心业务逻辑。领域模型的业务逻辑主要由实体和领域服务来实现。其中实体会采用充血模型来实现业务功能,如单一实体(或值对象)不能实现时,就交由领域服务进行组合和协调聚合内多个实体(或值对象),实现复杂的业务逻辑。

主要是封装了核心业务逻辑,并通过领域服务(Domain Service)和领域对象(Entities)的函数对外部提供业务逻辑的计算和处理;

5.4基础实施层(Infrastructure Layer):

主要包含Tunnel(数据通道)、防腐层,Config和Common。这里我们使用Tunnel这个概念来对所有的数据来源进行抽象,这些数据来源可以是数据库(MySQL,NoSql)、搜索引擎、文件系统、也可以是SOA服务等;Config负责应用的配置;Common是通用的工具类。

基础层贯穿DDD所有层。其职能:提供通用的技术和基础服务,包括第三方工具、驱动、消息中间件、网关、文件、缓存以及数据库等。

六、如何进行DDD领域驱动设计

DDD 包括战略设计战术设计两部分,它们分别从不同的视角出发,完成领域建模和微服务的拆分和设计。事件风暴(Event Storming)是落实领域驱动的一种常用方法,使用事件风暴能够通过领域事件来识别出聚合根,组合的聚合根则又组成限界上下文,限界上下文则正是我们寻找的“微服务”的概念。

6.1战略设计

是从业务视角出发,划分业务的领域边界,建立基于通用语言和业务上下文语义边界的限界上下文,构建领域模型。而限界上下文就可以作为微服务拆分和设计的边界。以一种领域专家、设计人员、开发人员都能理解的“通用语言”作为相互交流的工具,在不断交流的过程中发现和挖出一些主要的领域概念,然后将这些概念设计成一个领域模型;

6.2战术设计

则是从技术视角出发,侧重于对领域模型的技术实现,按照领域模型完成微服务的开发和落地。在战术设计中会有聚合、聚合根、实体、值对象、领域服务、领域事件、应用服务和仓储等领域对象,这些领域对象会以代码的形式映射到微服务中完成设计和系统落地。 由领域模型驱动软件设计,用代码来表现该领域模型。领域需求的最初细节,在功能层面通过领域专家的讨论得出。

七、领域模型建模

关系图:

关系图:

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

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

相关文章

python能成为编程届的网红么?

Python本身就是编程语言届的网红,Python,年龄可能比很多读者都要大,但是它在更新快速的编程界却一直表现出色,甚至有人把它比作是编程界的《葵花宝典》,只是Python的速成之法相较《葵花宝典》有过之而无不及。 但是能…

短视频矩阵系统.代码实时分享

短视频矩阵系统核心技术研发是为满足现代社交网络时代用户对视频分享和观看的需求而推出的一项技术。它旨在提供高质量的视频传输、智能推荐算法、实时互动等功能。短视频矩阵系统设计上考虑了多个关键技术,包括多媒体编解码技术、网络通讯技术、机器学习算法等。通…

[pgrx开发postgresql数据库扩展]附.更新开发环境安装脚本

pgrx更新到0.83之后,我本来还没感觉,但是我五一放假一来,发现我的WSL环境居然就挂了…… 果然是非稳定版本就是不靠谱了…… 所以我干脆搞了个虚拟机,重新安装了一套,还别说,更新到了0.83之后,安…

(十一)地理数据库创建——创建新的地理数据库

地理数据库创建——创建新的地理数据库 目录 地理数据库创建——创建新的地理数据库 1.地理数据库概述2.地理数据库建立一般过程2.1地理数据库设计2.2地理数据库建立2.2.1从头开始建立一个新的地理数据库2.2.2移植已经存在数据到地理数据库2.2.3用CASE工具建立地理数据库 2.3建…

学习HCIP的day.04

目录 七、关于OSPF的不规则区域问题 1、通过隧道链路(Tunnel) 2、OSPF的虚链路配置 3、多进程双向重发布 八、OSPF的数据库表 九、OSPF优化 1、汇总 2、特殊区域 --- 用于减少各个非骨干区域的LSA数量 七、关于OSPF的不规则区域问题 分为两种情…

【MySQL实战2 作业解析】

这里写自定义目录标题 作业回顾作业步骤完成方法恢复数据库设置查询日志的开关删除退市股票以及新股的无效交易日的数据删除个股数据表查询merged_table这张表里3开头的股票中每个月成交量最大的股票下载日志文件,备份数据库 作业回顾 作业内容发布在社区里&#x…

输入捕获模式测频率、PWMI模式测频率占空比

一、知识点 TIM输入捕获模式: 1、输入捕获模式测频率占空比 信号源:产生一个频率和占空比可调的波形 无信号发生器的情况:先用PWM模块,在PA0端口输出一个频率和占空比可调的波形,把PA0和PA6连在一起,PA6为输…

Ubuntu 安装 Mysql

主要内容 本文主要是实现在虚拟机 Ubuntu 18.04 成功安装 MySQL 5.7,并实现远程访问功能,以 windows 下客户端访问虚拟机上的 mysql 数据库。 1. 切换至 root 用户 ,shell 终端指令均执行在 root 用户下 sudo su 2. 安装并设置 mysql 安…

DOM操作-获取元素的方式

DOM—文档对象模型 ●DOM(Document Object Model): 文档对象模型 ●其实就是操作 html 中的标签的一些能力 ●或者说是一整套操作文档流的属性和方法的集合 ●我们可以操作哪些内容 ○获取一个元素 ○移除一个元素 ○创建一个元素 ○向页面里…

Unity防破解方案解析

Unity作为游戏开发市场第一大游戏引擎占有者,已经全面覆盖到各个游戏平台,在全球范围内超过50% 的手机游戏、PC 游戏和主机游戏都使用 Unity 创作而成。 同时,Unity也是中国游戏公司的首选开发引擎,《原神》《王者荣耀》《英雄联盟…

【MySQL入门指南】4种插入数据的方法

文章目录 MySQL的增删查改① - 增1.发生冲突则失败1.1 基本语法1.2 单行数据全列插入1.3 多行数据 指定列插入 2.发生冲突则更新2.1 基本语法2.2 插入否则更新 3.发生冲突则替换3.1 基本语法3.2插入否则替换 4.插入查询结果 MySQL的增删查改① - 增 -- 创建一张学生表 CREATE…

狂神 springcloud学习

springcloud学习 笔记整理来源 B站UP主狂神说https://www.bilibili.com/video/BV1jJ411S7xr 参考:菜鸟小杰子 https://blog.csdn.net/lijie0213/article/details/107914619 参考:路飞 https://csp1999.blog.csdn.net/article/details/106255122?spm100…

stm32cubemx配置mpu6050——10分钟0基础到灵活使用

stm32cubemx配置mpu6050——10分钟0基础到灵活使用 10分钟速通!你没看错,就是10min,从0基础到灵活运用mpu6050。 不信?往下看看就会:嗷~原来如此 第一步 下载github开源代码。 https://github.com/leech001/MPU6050首…

从零开始学习Linux运维,成为IT领域翘楚(六)

文章目录 🔥Linux磁盘管理🔥Linux挂载硬盘🔥Linux系统状态检测命令🔥Linux下载软件安装的命令 🔥Linux磁盘管理 分区的方式 🐟 MBR分区表:每块硬盘最大支持2.1TB硬盘,每块硬盘最多支…

《编程思维与实践》1042.字串变换

《编程思维与实践》1042.字串变换 题目 思路 分两步解决: 1.判断是否可以通过两种变换使所有的字符串变得相同; 2.在能变换的前提下使变换的次数最少。 其中第一步可以将每个字符串的基底(将连续重复出现的字符视为一个字符)求出来, 如: aaabbb的基底就…

28《Protein Actions Principles and Modeling》-《蛋白质作用原理和建模》中文分享

《Protein Actions Principles and Modeling》-《蛋白质作用原理和建模》 本人能力有限,如果错误欢迎批评指正。 第七章:Proteins Evolve (蛋白进化) 蛋白质分子可以通过生物进化而发生改变。随着生物体的进化,它们…

Haproxy集群

引言 Haproxy 是一个使用C语言编写的自由及开放源代码软件,其提供高可用性、负载均衡,以及基于TCP和HTTP的应用程序代理。 一、Haproxy简介 1、Haproxy应用分析 LVS在企业中康复在能力很强,但存在不足: LVS不支持正则处理&…

Java编程中的20种常见异常及其原因,你知道多少

本文介绍了在Java编程中可能遇到的20种常见异常,包括空指针异常、类未找到异常、数组下标越界异常等,并简要解释了每种异常发生的原因。这些异常可能由于编程错误、运行时资源不足或权限受限等多种原因触发,了解它们有助于更高效地进行程序调…

Crowdsoure的简单介绍

一、什么是Crowdsoure 在美国《连线》杂志2006年的6月刊上,记者Jeff Howe首次提出了Crowdsoure(众包)的概念。众包是一个框架,它将大量分散的人群聚集在一起,收集数据,解决问题,或应对挑战。它…

55、RK3588使用MPP编码yuv到h264、解码h264到yuv模块开发和测试

基本思想:需要使用独立模块代码去实现自己的逻辑功能,所以在基于官方源码基础上,和参考附录几个官方链接,搞出一版rk3588编码测试和解码测试demo 测试视频/生成h264/生成yuv 链接: https://pan.baidu.com/s/1HbpeqMJb8HcgFpzaKh…