15 | 边界:微服务的各种边界在架构演进中的作用?

news2024/9/22 17:36:14

目录

演进式架构

微服务还是小单体?

微服务边界的作用

逻辑边界

物理边界

代码边界

正确理解微服务的边界

总结


那重点落到边界的时候,总结一下就是,微服务的设计要涉及到逻辑边界、物理边界和代码边界等等。

那么这些边界在微服务架构演进中到底起到什么样的作用?我们又该如何理解这些边界呢?这就是我们今天重点要解决的问题。

演进式架构

在微服务设计和实施的过程中,很多人认为:“将单体拆分成多少个微服务,是微服务的设计重点。”可事实真的是这样吗?其实并非如此!

Martin Fowler 在提出微服务时,他提到了微服务的一个重要特征——演进式架构。那什么是演进式架构呢?演进式架构就是以支持增量的、非破坏的变更作为第一原则,同时支持在应用程序结构层面的多维度变化。

微服务不是一锤子拆分买卖,而是一种渐进性演变思路,它能够支持在需要拆分或调整时,不伤经动骨,只重新重新组合就能轻松实现。所以,微服务改造的重点是梳理清楚最根本的聚合与领域模型,而不是感性的切分到什么程度。切分可以随着需求变化、业务量变化、实现架构变化而变动,但底层的聚合与领域模型却是稳定的。

那如何判断微服务设计是否合理呢?其实很简单,只需要看它是否满足这样的情形就可以了:随着业务的发展或需求的变更,在不断重新拆分或者组合成新的微服务的过程中,不会大幅增加软件开发和维护的成本,并且这个架构演进的过程是非常轻松、简单的。

这也是微服务设计的重点,就是看微服务设计是否能够支持架构长期、轻松的演进。

那用 DDD 方法设计的微服务,不仅可以通过限界上下文和聚合实现微服务内外的解耦,同时也可以很容易地实现业务功能积木式模块的重组和更新,从而实现架构演进。

微服务还是小单体?

有些项目团队在将集中式单体应用拆分为微服务时,首先进行的往往不是建立领域模型,而只是按照业务功能将原来单体应用的一个软件包拆分成多个所谓的“微服务”软件包,而这些“微服务”内的代码仍然是集中式三层架构的模式,“微服务”内的代码高度耦合,逻辑边界不清晰,这里我们暂且称它为“小单体微服务”。

下面这张图也很好地展示了这个过程。

而随着新需求的提出和业务的发展,这些小单体微服务会慢慢膨胀起来。当有一天你发现这些膨胀了的微服务,有一部分业务功能需要拆分出去,或者部分功能需要与其它微服务进行重组时,你会发现原来这些看似清晰的微服务,不知不觉已经摇身一变,变成了臃肿油腻的大单体了,而这个大单体内的代码依然是高度耦合且边界不清的。

“辛辛苦苦好多年,一夜回到解放前啊!”这个时候你就需要一遍又一遍地重复着从大单体向单体微服务重构的过程。想想,这个代价是不是有点高了呢?

其实这个问题已经很明显了,那就是边界

这种单体式微服务只定义了一个维度的边界,也就是微服务之间的物理边界,本质上还是单体架构模式。微服务设计时要考虑的不仅仅只有这一个边界,别忘了还要定义好微服务内的逻辑边界和代码边界,这样才能得到你想要的结果。

那现在你知道了,我们一定要避免将微服务设计为小单体微服务,那具体该如何避免呢?清晰的边界人人想要,可该如何保证呢?DDD 已然给出了答案。

微服务边界的作用

你应该还记得 DDD 设计方法里的限界上下文和聚合吧?它们就是用来定义领域模型和微服务边界的。

我们再来回顾一下 DDD 的设计过程。

在事件风暴中,我们会梳理出业务过程中的用户操作、事件以及外部依赖关系等,根据这些要素梳理出实体等领域对象。根据实体对象之间的业务关联性,将业务紧密相关的多个实体进行组合形成聚合,聚合之间是第一层边界。根据业务及语义边界等因素将一个或者多个聚合划定在一个限界上下文内,形成领域模型,限界上下文之间的边界是第二层边界。

为了方便理解,我们将这些边界分为:逻辑边界、物理边界和代码边界

逻辑边界

逻辑边界主要定义同一业务领域或应用内紧密关联的对象所组成的不同聚类的组合之间的边界。事件风暴对不同实体对象进行关联和聚类分析后,会产生多个聚合和限界上下文,它们一起组成这个领域的领域模型。微服务内聚合之间的边界就是逻辑边界。一般来说微服务会有一个以上的聚合,在开发过程中不同聚合的代码隔离在不同的聚合代码目录中。

逻辑边界在微服务设计和架构演进中具有非常重要的意义!

微服务的架构演进并不是随心所欲的,需要遵循一定的规则,这个规则就是逻辑边界。微服务架构演进时,在业务端以聚合为单位进行业务能力的重组,在微服务端以聚合的代码目录为单位进行微服务代码的重组。由于按照 DDD 方法设计的微服务逻辑边界清晰,业务高内聚,聚合之间代码松耦合,因此在领域模型和微服务代码重构时,我们就不需要花费太多的时间和精力了。

现在我们来看一个微服务实例,在下面这张图中,我们可以看到微服务里包含了两个聚合的业务逻辑,两个聚合分别内聚了各自不同的业务能力,聚合内的代码分别归到了不同的聚合目录下。

那随着业务的快速发展,如果某一个微服务遇到了高性能挑战,需要将部分业务能力独立出去,我们就可以以聚合为单位,将聚合代码拆分独立为一个新的微服务,这样就可以很容易地实现微服务的拆分。

另外,我们也可以对多个微服务内有相似功能的聚合进行功能和代码重组,组合为新的聚合和微服务,独立为通用微服务。现在你是不是有点做中台的感觉呢?

物理边界

物理边界主要从部署和运行的视角来定义微服务之间的边界。不同微服务部署位置和运行环境是相互物理隔离的,分别运行在不同的进程中。这种边界就是微服务之间的物理边界。

代码边界

代码边界主要用于微服务内的不同职能代码之间的隔离。微服务开发过程中会根据代码模型建立相应的代码目录,实现不同功能代码的隔离。由于领域模型与代码模型的映射关系,代码边界直接体现出业务边界。代码边界可以控制代码重组的影响范围,避免业务和服务之间的相互影响。微服务如果需要进行功能重组,只需要以聚合代码为单位进行重组就可以了。

正确理解微服务的边界

从上述内容中,我们知道了,按照 DDD 设计出来的逻辑边界和代码边界,让微服务架构演进变得不那么费劲了。

微服务的拆分可以参考领域模型,也可以参考聚合,因为聚合是可以拆分为微服务的最小单位的。但实施过程是否一定要做到逻辑边界与物理边界一致性呢?也就是说聚合是否也一定要设计成微服务呢?答案是不一定的,这里就涉及到微服务过度拆分的问题了。

微服务的过度拆分会使软件维护成本上升,比如:集成成本、发布成本、运维成本以及监控和定位问题的成本等。在项目建设初期,如果你不具备较强的微服务管理能力,那就不宜将微服务拆分过细。当我们具备一定的能力以后,且微服务内部的逻辑和代码边界也很清晰,你就可以随时根据需要,拆分出新的微服务,实现微服务的架构演进了。

当然,还要记住一点,微服务内聚合之间的服务调用和数据依赖需要符合高内聚松耦合的设计原则和开发规范,否则你也不能很快完成微服务的架构演进。

总结

今天我们主要讨论了微服务架构设计中的各种边界在架构演进中的作用。

逻辑边界:微服务内聚合之间的边界是逻辑边界。它是一个虚拟的边界,强调业务的内聚,可根据需要变成物理边界,也就是说聚合也可以独立为微服务。

物理边界:微服务之间的边界是物理边界。它强调微服务部署和运行的隔离,关注微服务的服务调用、容错和运行等。

代码边界:不同层或者聚合之间代码目录的边界是代码边界。它强调的是代码之间的隔离,方便架构演进时代码的重组。

通过以上边界,我们可以让业务能力高内聚、代码松耦合,且清晰的边界,可以快速实现微服务代码的拆分和组合,轻松实现微服务架构演进。但有一点一定要格外注意,边界清晰的微服务,不是大单体向小单体的演进。

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

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

相关文章

vue清除地址栏参数(可以单个,可以多个)

需求 vue跳转新页面后,清除url里面的参数,就是上一个页面带过来的参数,只用一次 mounted () {this.$nextTick(() > {let url this.getnewurl()window.history.replaceState(null, null, url);})},methods: { //根据参数名去清除&#xf…

深度学习训练营之调用Gensim来训练Word2Vec模型

深度学习训练营之调用Gensim来训练Word2Vec模型 原文链接环境介绍前置工作下载Gensim库对于原始语料进行分词添加停用词 模型训练模型介绍模型正式训练 计算词频 原文链接 🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍦 参考文章&#…

C#:了解LINQ,简化数据查询和操作的强大工具

文章目录 linq关键字fromwhereselectorderbyjoingroupletinto linq方法筛选方法WhereOfType 排序方法:OrderByOrderByDescendingThenByThenByDescending 投影方法:SelectSelectMany 分组方法:GroupBy 连接方法:JoinGroupJoin 聚合…

高效方案:30万条数据插入 MySQL 仅需13秒

本文主要讲述通过MyBatis、JDBC等做大数据量数据插入的案例和结果。 30万条数据插入插入数据库验证 实体类、mapper和配置文件定义 User实体 mapper接口 mapper.xml文件 jdbc.properties sqlMapConfig.xml 不分批次直接梭哈 循环逐条插入 MyBatis实现插入30万条数据 J…

SpringBoot 集成 MybatisPlus 一——介绍

MybatisPlus 是 Mybatis 的升级版本,是对 Mybatis 的简化,因为他们的口号就是“为简化开发而生”。 1、创建数据表 CREATE TABLE ​​User​​ ( ​​id​​ INT NOT NULL, ​​username​​ VARCHAR(50) NULL DEFAULT NULL, ​​gendar​​ CHAR(2) NU…

了解微服务架构

微服务架构 软件架构历史 Software As A Service,这不仅仅是⼀个理念,它更多释放的是企业在新⼀轮的市场竞争中,如何使⽤轻量级的组织架构和新的软件架构来更好的服务企业⾯向未来的战略调整和市场定位,从⽽赢得未来的市场空间。…

【计算机视觉 | 图像分割】arxiv 计算机视觉关于图像分割的学术速递(7 月 6 日论文合集)

文章目录 一、分割|语义相关(15篇)1.1 Prompting Diffusion Representations for Cross-Domain Semantic Segmentation1.2 ZJU ReLER Submission for EPIC-KITCHEN Challenge 2023: Semi-Supervised Video Object Segmentation1.3 Multi-Modal Prototypes for Open-Set Semanti…

基于YOLO的3D人脸关键点检测方案

目录 前言一、任务列表二、3D人脸关键点数据H3WB2.下载方法3.任务4.评估5.使用许可 3DFAWAFLW2000-3D 三、3D关键点的Z维度信息1.基于3DMM模型的方法2.H3WB 四、当前SOTA的方法1.方法1 五、我们的解决方法1.数据转为YOLO格式2.修改YOLO8Pose的入口出口3.开始训练,并…

aardio 的addHeaders请求

aardio群 625494397 废话不多说 直接开干! import web.json; import console; import inet.whttp; web.json.parse( json );//转化json格式 h.addHeaders {Accept-Encoding gzip, deflate, br;Accept-Language zh-CN,zh;q0.9;User-Agent Mozilla/5.0 (Windows …

浅谈智能照明控制管理系统的功能介绍

安科瑞电气股份有限公司 上海嘉定 201801 摘要:智能照明控制系统较好地实现了智能控制、人性化照明和节能降耗的功能,使其在楼宇控制领域变得越来越重要,越来越受到人们的重视。本文介绍了智能照明控制系统的概念、特点、优势、发展方向等内容,并着重对智能照明控制…

多个项目的进度管理:掌握这3点,轻松应对

在现代的企业竞争中,许多企业组织都会同时进行多个项目。而有效的进度管理对于确保项目按时交付和优化资源利用至关重要。那么有哪些方法可以帮助项目管理者掌握多个项目的进度管理呢? 一:明确目标和优先级 在管理多个项目时,明确…

windows系统使用nvm实现多版本node切换

介绍nvm 是 node version manager(node 版本管理工具)的缩写,是一个命令行工具,用于管理和切换到不同版本的 node.js。 不同的项目可能需要不同版本的 node.js 和 npm(node 包管理器),例如&…

增强型视觉系统 (EVS)

增强型视觉系统 EVS 1、增强型视觉系统概览2、车载相机 HAL2.1 EVS 应用2.2 EVS 管理器2.3 EVS HIDL 接口2.4 内核驱动程序 《增强型视觉系统 (EVS) 1.1 集成指南》 车载相机 HAL 1、增强型视觉系统概览 为了增强视频串流管理和错误处理,Android 11 更新了车载相机…

OD查找偏移表达式

1、在CE中先找到血地址2DF94C28 2、在od数据段dd 血地址 dd 2DF94C28查找到数据 3、在血地址位置右键-断点-硬件访问-DWORD,再操作游戏会再改变这个地址代码段下断点,查找到 4、验证查找的是否正确,在8199FA处下断点,dd edi288处…

github port 22 connection refused 不通过科学上网连接不上问题

原因是用密钥连接github走的是ssh,ssh默认端口是22没有加密,github不让走22 解决办法是在 ~/.ssh/config里添加 Host github.com Hostname ssh.github.com Port 443 让ssh连github的时候走443端口,TLS加密的 ssh -T gitgithub.com 说明已…

Docker深入

一、简介 Docker是一个用于构建、运行、传送应用程序的平台。 2、为什么使用Docker 在部署服务器过程中,配置各种环境变量、第三方依赖等等,耗费时间太长,使用Docker可以将他们打包成一个集装箱,只要在开发环境中运行成功&…

Hive 复习重点

文章目录 特点SQL查询转换成MR作业的过程内部表 & 外部表 & 分区表 & 分桶表内部表外部表分区表 分桶表DQL语法性能优化SQL语句优化数据格式化 ORC, Parquet列式存储小文件过多优化并行执行优化JVM 优化推测执行行列过滤limit 限制本地模式(开启MR,单机…

stm32mp157——通过按键中断实现LED灯的亮灭

EXTI章节初始化 void hal_exit_init(EXTI编号,GPIOF组编号,中断触发方式) 调用:hal_exit_init(EXTI9,0x05,下降沿触发) 调用: hal_exit_init(EXTI7,0x05,下降沿触发) 调用: hal_exit_init(EXTI8,0x05,下降沿触发) GIC章节初始化 void hal_gic_init(中断号,中断优先级) 调用: ha…

Redis - 一篇讲解根据 Key 前缀统计分析内存占用

问题描述 今天遇到一个 Redis 内存打挂了的问题,想看看哪个前缀 Key 占用内存比较大?! 原因分析 我们都知道如果直接用 Keys 参数去做统计很危险,而且也只能统计数量,当然也可以排序去前几名的占用内存 Key 对应的大…

ESP32(掌控板) 电子琴

ESP32(掌控板) 电子琴 本程序实现了电子琴功能,通过机械按键改变变量的值实现“翻页”(每个八度分两页,共六页),通过触摸按键弹奏(包含半音),屏幕显示当前触摸…