微服务拆分

article/2025/10/3 0:55:22

如何定义一个微服务架构?通常情况下,定义应用程序架构分三步。但是,世界上并没有一个机械化的流程可以遵守,然后指望这个流程输出一个合理的架构。这里只能介绍一个笼统的方法,现实世界中,这是一个不断迭代和持续创新的过程。跟所有的软件开发一样,定义架构是一项艺术而非技术。
一开始我们需要拿到领域专家或现有应用的需求文档,定义应用架构的第一步则是将应用的需求提炼为各种关键请求。可以使用系统操作(System Operation)来描述这些请求。系统操作是应用必须处理的请求的一种抽象描述。它既可以是更新数据的命令,也可以是检索数据的查询。第二步是确定如何分解服务。有几种策略可供选择。一种源于业务架构学派的策略是定义与业务能力相对应的服务。另一种策略是围绕软件驱动设计的子域来分解和设计服务。但这些策略的最终结果都是围绕业务概念而非技术概念分解和设计服务第三步是确定每个服务的API。为此,架构师需将第一步标识的每个系统操作分配给服务。服务可以完全独立地实现操作。或者,它可能需要多个服务协作。在这种情况下,可以确定服务的协作方式,这通常需要服务来支持其他操作。
由于需求通常由领域专家或现有需求给出,所以微服务架构架构师的主要职责是第二步(确定如何分解服务)和第三步(确定每个服务的API)。由于第三步依赖第二步,所以对架构师来说,服务拆分是微服务架构落地的关键。然后如何将系统操作划分到各个服务中,并定义服务API。

服务拆分标准

服务拆分有几个障碍需要克服。首先是网络延迟。由于服务之间的网络往返可能太多,特定的分解是不切实际的。分解的另一个障碍是服务之间的同步通信降低了整个应用的可用性。第三个障碍是需要维护跨服务的数据一致性。第四个障碍就是上帝类(God Class)问题。它广泛存在整个应用中。
软件开发领域追求松耦合和高内聚,微服务开发也不例外,在进行服务拆分时,尽量保证服务自身高度内聚,服务间松散耦合。松耦合和高内聚这两个概念在不同的上下文中使用,如面向对象编程中,这里先讨论着两个概念在微服务中的含义。

松耦合

如果做了服务之间的松耦合,那么修改一个服务就不需要修改另一个服务。使用微服务最重要的一点是,能够独立修改及部署单个服务而不需修改系统的其他部分。
对于紧耦合方式做服务之间的集成,会导致一个服务的修改使其消费者同步修改,这与微服务概念不符。一个松耦合的服务,应该尽可能少地知道与之协作的那些服务的信息。这也意味着,应该限制两个服务之间不同调用形式的数量,因为除了潜在的性能问题之外,过度的通信可能会导致紧耦合。
服务之间的交互采用API完成,这样做就封装了服务的实现细节。这允许服务在不影响客户端的情况下,对实现方式作出修改。松耦合服务是改善开发效率、提升可维护性和可测试性的关键。小的、松耦合的服务更容易被理解、修改和测试。
服务通过API来实现服务间调用,这样就避免了外界对服务的数据库的直接访问和调用。服务自身持久化数据就如同类的私有属性一样,是不对外的。保证数据的私有属性是实现松耦合的前提之一。这样做,就允许开发者修改服务的数据结构,而不同提前与其他服务的开发者相互协商。这样做在运行时也实现了更好的隔离。例如,一个服务的数据库加锁不会影响另外的服务。

高内聚

高内聚就是将相关的行为聚集在一起,把不相关的行为放到别处。这样做的话,如果改变某个行为的话,可以只在一个地方修改,然后尽快的发布。如果需要在多个不同的地方做修改,那么可能就需要同时发布多个微服务才能交付这个功能。在多个不同的地方进行修改会很慢,同时部署多个服务风险也很高,这两者都是要极力避免的。所以,找到问题的边界就可以确保相关的行为能放在同一个地方,并且它们会和其他边界以尽量松耦合的形式进行通信。

服务拆分实现

微服务架构的关键是如何进行功能分解,也就是说如何将一个大型的应用构建为一组服务。在进行拆分前,再次声明下微服务理解上的误区。微服务这个术语的一个问题是让开发者将关注点错误的聚焦在上。它暗示服务应该非常小。其他基于大小的术语也是如此。实际上,大小不是一个重要的考虑因素。更好的目标是将精心设计的服务定义为能力由小团队开发的服务,并且交付时间最短,与其他团队协作最少。理论上,团队可能值负责单一服务,因此服务绝不是微小的。相反,如果服务需要大型团队或需要很长时间进行测试,那么拆分团队或服务可能是有意义的。另外,如果因为其他服务的变更而不断需要同步更新自己团队负责的服务,或者所需负责服务正在触发其他服务的同步更新,那么这表明服务没有实现松耦合。这表明构建的可能是一个分布式的单体应用
和定义微服务架构一样,服务拆分也不是一个机械化的流程。相反,有多种拆分策略可供选择。每一种都是从一个侧面来解决问题,并且使用它们独有的一些术语。这里重点介绍两种服务拆分策略,一种是根据业务能力进行服务拆分,另一种是根据领域驱动设计进行服务拆分。

业务拆分

创建微服务架构的策略之一就是根据业务能力进行服务拆分业务能力是一个来自于业务架构建模的术语。业务能力是指一些能够为公司(或组织)产生价值的商业活动。如在线商店的业务能力包括:商品管理、购物车管理、订单管理、库存管理、发货、退货等。
组织的业务能力通常是指这个组织的业务是做什么,它们通常是稳定的。与之相反,组织采用何种方式来实现它的业务能力,是随着时间不断变化的。如数字化推动了商业流程的线上化、自动化。如之前购物,需要到线下实体店购买,而随着互联网的兴起,在线购物已经成为主流。虽然,购物的形式发生了很大的变化,但是购物这项业务并没有变化。
一个组织拥有哪些业务能力,是通过对组织的目标、结构和商业流程的分析得来的。每一个业务能力都可被认为是一个服务,除非它是面向技术的而非面向业务的。这里以餐馆系统为例,介绍下如何基于业务拆分服务。常见的餐馆系统有如下能力:
(1) 餐馆菜单和其他信息管理,如营业地址和时间。
(2) 消费者管理,消费者相关信息管理。
(3) 订单获取和履行。(a) 消费者创建和管理订单。(b) 餐馆管理订单的生产过程。© 送餐。
(4) 会计记账。(a) 管理跟消费者相关的记账。(b) 管理跟餐馆相关的记账。
(5) 其他能力。
确定了业务能力后,接下来就可以为每个能力或相关能力组定义服务,也即将业务能力映射到服务。决定将哪个级别的能力层次结构映射到服务是一个非常主观的判断。这里进行如下划分:
请添加图片描述
在上面的服务,将一个业务能力映射为一个服务,在实际的划分中,也存在将多个业务能力划分到一个服务的场景。
围绕能力组织服务的一个关键好处是,因为业务能力是稳定的,所以最终的架构也相对稳定。架构的各个组件可能会随着业务的具体实现方式的变化而发展,但架构仍保持不变。但是,随着时间的推移,可能部分功能因为过多的进程间通信而导致特定的分解效率低下,导致需要将这些服务合并在一起。相反,服务可能会在复杂性方面增长到值的将其拆分为多个服务的程度。所以,服务拆分不是一次性工作,应随着领域认知的加深,按需进行服务合并或服务拆分。

DDD拆分

Eric Evans 提出的领域驱动设计是构建复杂软件的方法论,这些软件通常都以面向对象和领域模型为核心。领域模型以解决具体问题的方式包含了一个领域内的知识。领域模型会被紧密地映射到应用的设计和实现环节。在微服务架构的设计层面,DDD有两个特别重要的概念,子域和限界上下文。
传统的企业架构建模会为整个企业建立一个单独的模型,在这样的模型中,会有适用于整个应用全局的业务实体定义,这类传统建模方式的挑战在于,让组织内的所有团队都对全局单一的建模和术语定义达成一致是困难的。另外,对于组织中的特定团队而言,这个单一的业务实体定义可能过于复杂,超出了他们的需求。DDD则定义多个领域模型,且每个模型都有明确的范围。
领域驱动为每一个子域定义单独的领域模型,子域是领域的一部分,领域是DDD中用来描述应用问题域的一个术语。识别子域的方式跟识别业务能力一样:分析业务并识别业务的不同专业领域,分析产出的子域定义结果也会跟业务能力非常接近。
DDD把领域模型的边界称为限界上下文(Bounded Context)。限界上下文包括实现这个模型的代码集合。当使用微服务架构时,每一个限界上下文对应一个或一组服务。换言之,通过DDD的方式定义子域,并把子域对应为一个服务,这样就完成了服务拆分的工作。基于业务拆分的实例餐馆系统的领域划分如下:
请添加图片描述
DDD和微服务架构十分契合。DDD的子域和限界上下文的概念,可以很好地跟微服务架构中的服务进行匹配。而且,微服务架构中的自治团队负责服务开发的理念,也跟DDD中每个领域模型由一个独立团队负责开发的理念吻合。另外,子域用于它自己的领域模型这个概念,为消除上帝类和优化服务拆分提供了方法。

参考

微服务设计 Sam Newman 著, 崔力强 等 译
微服务架构设计模式 Chris Richardson 著, 陈斌 等 译


http://chatgpt.dhexx.cn/article/euxKZroO.shtml

相关文章

每日一题:为什么要进行系统拆分?

原文来自 GitHub 开源社区 Doocs,欢迎 Star 此项目,如果你有独到的见解,同样可以参与贡献此项目。 面试题 为什么要进行系统拆分?如何进行系统拆分?拆分后不用 dubbo 可以吗? 面试官心理分析 从这个问题开始…

个人对系统拆分的理解

在本人现在的公司和本人工作过的上一家公司,本人有幸参与并实施了公司业务系统的架构拆分,现将之前的工作总结下。 1,为什么要进行系统拆分 首先我们需要想想,到底什么样的系统需要进行拆分?并不是所有的系统都需要进…

登录+注册界面的实现(代码)

先看效果图&#xff01; 话不多说&#xff0c;直接上代码&#xff01; //布局文件&#xff1a;activity_login.xml <?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android&qu…

简单WEB登录页面代码实现

longin.html&#xff1a;登录页面&#xff0c;此处action引用**/**类型的地址&#xff0c;JSP可以用${ pageContext.request.contextPath }/LS <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd&qu…

编写简单的登陆页面

1.简单登录界面&#xff08;自己设置css样式&#xff09; 代码如下 <form id"loginForm" action"#" method"post" novalidate"novalidate"><div class"login_box"><div class"login_box_left"&g…

实现网页登录代码

python 一、前言 本文通过selenium工具实现工作所用网站的自动登录&#xff0c;下图为网站登录界面。 1、运行环境 操作系统&#xff1a;Windows10 python版本&#xff1a;python3.7 2、需要的python第三方库 1、selenium 安装&#xff1a; pip install selenium selen…

【html】【一个简单的用户登录页面代码】

结果 代码 <!DOCTYPE html> <html><head><title>用户登录.html</title><meta http-equiv"keywords" content"keyword1,keyword2,keyword3"><meta http-equiv"description" content"this is my pag…

html 【一个简单的用户登录页面代码】

效果图 <!DOCTYPE html> <html><head><title>用户登录.html</title><meta http-equiv"keywords" content"keyword1,keyword2,keyword3"><meta http-equiv"description" content"this is my page&…

简单登录页面html代码

【实例简介】 js/html基础示例&#xff1a;简单登录页面 【实例截图】 【核心代码】 文档&#xff1a;590m.com/f/25127180-496787472-732294&#xff08;访问密码&#xff1a;551685&#xff09; 以下内容无关&#xff1a; -------------------------------------------分…

登录界面源代码

拿走请三联&#xff0c;并注明出处&#xff01; 没有上传原背景图&#xff0c;使用的话需自己更改图片名称 可连接注册界面&#xff0c;和用户照片墙&#xff0c;此文只有登录界面代码&#xff0c;代码存在些许问题&#xff0c;望观看的大佬们多多指教&#xff01; <!DOC…

python实现网站的自动登录(selenium实现,带验证码识别)

python实现网站自动登录&#xff08;selenium实现&#xff0c;带验证码识别&#xff09; 一、前言 这是鄙人写的第一篇博客&#xff0c;旨在总结一下近期所学&#xff0c;本文通过selenium工具实现工作所用网站的自动登录&#xff0c;下图为网站登录界面。 1、运行环境 操作…

登录页面的代码

登录页面的代码 在把页面和数据库做好之后&#xff0c;我的登录页面只需要 用户名和密码 &#xff0c;所以代码比较简单。 先找到登录按钮&#xff0c;给一个点击事件&#xff0c;然后再获取他们的表单值&#xff0c;然后对用户名和密码进行判断&#xff0c;判断是否填写了资料…

核函数(多项式,高斯核)以及svm解决回归问题

文章目录 一、SVM最优化问题转换1、多项式核函数 二、高斯核函数1.引入库1、多项式特征2、高斯核函数升维举例3、高斯核函数超参数gamma 三、svm解决回归问题总结 一、SVM最优化问题转换 变换为数学上一个更好解的 在这个式子中有重要的一项Xi&#xff0c;Xj 两个样本的点乘…

高斯核-高斯模糊

大白话高斯模糊 以二维高斯为例&#xff0c;公式&#xff1a; 高斯模糊的原理,可以理解成每一个像素都取周边像素的加权平均值 以高斯分布取g矩阵的值得到的模糊方法即为高斯模糊 权重矩阵 假定中心点的坐标是&#xff08;0,0&#xff09;&#xff0c;那么距离它最近的8个点的…

数值实验-高斯核函数 python/matlab 实现

支持向量机 支持向量&#xff1a;支持平面把两类类别划分开的超平面的向量点机&#xff1a;一种算法SVM 是一种二分类模型线性可分支持向量机&#xff1a;通过硬间隔最大化&#xff0c;学习一个线性分类器线性支持向量机&#xff1a;通过软间隔最大化&#xff0c;学习一个线性…

CS131专题-2:高斯核、噪声、滤波

目录 1 高斯核 1.1 一维定义 1.2 二维定义 1.2.1 应用高斯核的过程 1.2.2 不同σ值的高斯核情况 1.2.3 不同核宽度情况 1.2.4 高斯核&#xff08;滤波&#xff09;特性 1.2.5 使用高斯核做平滑滤波相对箱式滤波的优点 2 噪声 和 滤波 2.1 椒盐噪声、脉冲噪声 2.1.1 …

python高斯核函数_机器学习:SVM(核函数、高斯核函数RBF)

一、核函数(Kernel Function) 1)格式 K(x, y):表示样本 x 和 y,添加多项式特征得到新的样本 x、y,K(x, y) 就是返回新的样本经过计算得到的值; 在 SVM 类型的算法 SVC() 中,K(x, y) 返回点乘:x . y 得到的值; 2)多项式核函数 业务问题:怎么分类非线性可分的样本…

高斯整数matlab,Matlab---自适应高斯核

MCNN提出了适用于高密度人群的自适应高斯核: 笔者所理解的自适应高斯核函数: %function:通过高斯核产生相应的密度矩阵 %parameter: im:输入图像,灰度图; points:标注的点[X Y],n*2的矩阵 function im_density = get_density_map_autogaussian(im,points) im_density =…

高斯核原理详解+生成高斯核的Python代码

要搞清楚高斯核的原理的话&#xff0c;把下面这篇博文认认真真看一遍就可以了&#xff0c;链接如下&#xff1a; https://blog.csdn.net/u013066730/article/details/123112159 下面是我认为值得注意和需要补充说明的几点&#xff1a; 1 为什么高斯滤波能够让图像实现模糊化&a…

C语言哈希表UT_hash的使用方法详解

由于C语言本身不存在哈希,因此&#xff0c;我们可以调用开源的第三方头文件&#xff0c;这只是一个头文件&#xff1a;uthash.h&#xff0c;使用时只需要在文件首部编写#include<uthash.h>即可。 uthash的使用 #include "uthash.h" struct my_struct {int id…