28、架构-边界:微服务的粒度
微服务的粒度
在设计微服务架构时,确定微服务的粒度是一个关键问题。粒度过大或过小都会带来不同的问题,因此需要找到合理的粒度来划分微服务。下面详细探讨微服务粒度的合理范围及其影响因素。
1. 微服务粒度的上下界
微服务的粒度不应该只有唯一正确的答案或绝对的标准,但应该有个合理的范围,称为微服务粒度的上下界。
下界:独立、内聚、完备
-
独立:微服务应该能够独立发布、独立部署、独立运行和独立测试。每个微服务应该是一个独立的实体,能够在不依赖其他服务的情况下运行和测试。
具体实践:
- 独立部署流水线:为每个微服务设置独立的CI/CD流水线,确保服务可以独立构建、测试和部署。
- 独立运行环境:使用容器化技术(如Docker)为每个微服务提供隔离的运行环境,确保服务可以独立启动和运行。
-
内聚:微服务应该具有高内聚性,即强相关的功能和数据应该在同一个服务中处理,避免跨服务调用带来的复杂性和性能开销。
具体实践:
- 功能划分:确保每个微服务专注于一个特定的业务功能,例如用户管理、订单处理、支付处理等。
- 数据归属:将相关的数据放在同一个微服务中,避免跨服务的数据共享和操作。
-
完备:微服务应该包含至少一项完整的业务功能,确保其功能的完备性。例如,将字符串处理这样的小功能设计为一个微服务是不合适的,微服务应该处理完整的业务逻辑。
具体实践:
- 业务功能划分:确保每个微服务具有完整的业务功能,例如订单服务应该包含订单创建、修改、取消等完整的订单处理功能。
- 接口设计:设计微服务的API时,确保其功能接口完备,满足业务需求。
上界:团队规模和研发周期
-
团队规模:微服务的粒度应该与一个团队在一个研发周期内能够完成的全部需求范围相匹配。通常,一个理想的开发团队规模是6到12人,这就是所谓的“2 Pizza Team”原则,即一个团队的工作量应能在一个研发周期内由两个披萨喂饱的团队完成。
具体实践:
- 团队划分:将开发团队划分为多个小团队,每个团队负责一个或多个微服务,确保团队规模适中,便于管理和协作。
- 任务分配:根据团队的规模和能力,合理分配开发任务,确保每个团队在一个研发周期内能够完成所负责的微服务的开发和维护。
-
研发周期:根据研发模式的不同,研发周期可以是一天、两天、一周或两周。微服务的粒度应该适应团队的研发周期,确保在一个周期内能够完成对应的开发任务。
具体实践:
- 短周期迭代:采用敏捷开发方法,将开发周期划分为多个短周期(如一周或两周),确保每个周期内都能完成一定量的开发任务。
- 持续集成:通过持续集成工具,确保每个周期内的开发成果能够及时集成和测试,提高开发效率和质量。
2. 粒度过小的影响
如果微服务的粒度设计得过小,会带来以下几个方面的问题:
-
性能问题:一次进程内的方法调用耗时在数百个时钟周期内,而一次跨服务的方法调用则需要进行网络传输、参数序列化和结果反序列化,耗时可达毫秒级别。这种性能差距可能导致系统效率下降。
具体实践:
- 性能评估:在设计微服务时,进行性能评估,避免将高频调用的功能拆分为独立的微服务,减少跨服务调用的开销。
- 批量处理:对于需要频繁调用的功能,可以采用批量处理的方式,减少网络传输的次数和开销。
-
数据一致性问题:每个微服务都有自己独立的数据源,如果多个微服务需要协同工作以保证数据的一致性,处理过程会变得复杂。如果某些数据必须保证强一致性,那么这些数据应当聚合在同一个微服务中,而不是通过跨服务调用来实现。
具体实践:
- 事务管理:采用分布式事务管理(如SAGA模式)来处理跨服务的数据一致性问题,确保数据的一致性和完整性。
- 数据聚合:将需要强一致性的数据聚合在同一个微服务中,避免跨服务的数据一致性问题。
-
服务可用性问题:服务之间是松散耦合的依赖关系,微服务架构中无法也不应该假设被调用的服务具有绝对的可用性。如果两个微服务必须依赖对方才能正常工作,那么它们应当合并到同一个微服务中。
具体实践:
- 服务合并:对于高度依赖的服务,将它们合并为一个微服务,减少跨服务的依赖关系,提高系统的稳定性和可靠性。
- 降级策略:为每个微服务设计降级策略,确保在依赖的服务不可用时,系统能够降级运行,保证核心功能的正常运转。
3. 粒度过大的影响
如果微服务的粒度过大,虽然技术上没有问题,但从团队协作和管理的角度来看,会带来以下问题:
-
沟通成本:根据《人月神话》的结论,软件项目中的沟通成本随着参与人数的增加而指数增长。一个过大的微服务需要多个团队协作,沟通成本和管理难度会显著增加。
具体实践:
- 分层管理:将过大的微服务划分为多个子服务,通过分层管理的方式,减少沟通成本和管理难度。
- 团队职责明确:为每个团队明确职责和分工,减少团队间的依赖和协调,提高沟通效率。
-
灵活性下降:过大的微服务会降低系统的灵活性,使得独立部署和更新变得更加困难,失去了微服务架构的主要优势之一。
具体实践:
- 细化服务:将过大的微服务细化为多个粒度适中的微服务,确保每个微服务都能独立部署和更新,提高系统的灵活性。
- 模块化设计:采用模块化设计方法,将微服务拆分为多个模块,通过接口进行通信,保持系统的灵活性和可扩展性。
4. 领域驱动设计(DDD)的方法论
当今软件业界对识别微服务边界已取得较为一致的观点,即采用领域驱动设计(Domain-Driven Design, DDD)来指导具体实践。DDD 提供了以下几个重要概念和方法:
-
界限上下文(Bounded Context):界限上下文是定义微服务边界的关键概念。每个界限上下文代表一个特定的业务领域,微服务的边界应与界限上下文保持一致。
具体实践:
- 识别界限上下文:通过业务需求分析,识别系统中的界限上下文,为每个界限上下文定义对应的微服务。
- 界限上下文映射:绘制界限上下文映射图,明确各个界限上下文之间的关系和依赖,为微服务的设计提供指导。
-
聚合(Aggregate):聚合是DDD中的基本构建块,表示一组具有内聚关系的对象。微服务应根据聚合来划分,确保每个服务具有高内聚性和低耦合性。
具体实践:
- 识别聚合:通过领域模型分析,识别系统中的聚合,将每个聚合作为一个独立的微服务。
- 聚合内协作:确保聚合内部的协作在同一个微服务中进行,减少跨服务的依赖和通信。
-
领域事件(Domain Event):领域事件用于在不同的微服务之间进行通信和协作,确保数据的一致性和业务逻辑的完整性。
具体实践:
- 发布领域事件:当一个微服务的状态发生变化时,通过发布领域事件通知其他相关服务,确保数据和业务逻辑的一致性。
- 事件驱动架构:采用事件驱动架构,使用消息队列(如Kafka、RabbitMQ)来传递领域事件,实现微服务之间的解耦和协作。
总结
微服务的粒度设计是微服务架构中的一个关键问题。合理的微服务粒度应该满足独立、内聚和完备的要求,同时应考虑团队规模和研发周期的实际情况。通过领域驱动设计的方法论,架构师可以更好地识别和划分微服务边界,确保系统的灵活性、可维护性和高效性。
相关文章:
28、架构-边界:微服务的粒度
微服务的粒度 在设计微服务架构时,确定微服务的粒度是一个关键问题。粒度过大或过小都会带来不同的问题,因此需要找到合理的粒度来划分微服务。下面详细探讨微服务粒度的合理范围及其影响因素。 1. 微服务粒度的上下界 微服务的粒度不应该只有唯一正确…...

开源API网关-ApacheShenYu首次按照启动遇到的问题
一.背景 公司有API网关产品需求,希望有图形化的后台管理功能。看到了ApacheShenYu,作为Apache的顶级项目,直接认可了。首先,感谢各位大神的付出,初步看这个项目是国内大厂中的大神创立的,在此表示膜拜&…...

uniapp获取证书秘钥、Android App备案获取公钥、签名MD5值
一、 uniapp获取证书秘钥 打开uniapp开发者中心下载证书打开cmd输入以下这段代码,下载提供查看到的密钥证书密码就可以了!下载证书在 java 环境下运行才可以 // your_alias 换成 证书详情中的别名,your_keystore.keystore 改成自己的证书文件…...
QT 如何储存多种数据类型(QVariant )
QVariant 是 Qt 框架中用于存储各种数据类型的类。它提供了一个强大的类型系统,允许你在运行时存储和检索多种类型的数据,而不需要在编译时确定类型。QVariant 的主要优点在于它的灵活性和通用性,这使得它在 Qt 的很多组件和机制中都被广泛使…...
持续总结中!2024年面试必问的操作系统面试题(九)
上一篇地址:持续总结中!2024年面试必问的操作系统面试题(八)-CSDN博客 十七、解释什么是操作系统的安全性和它的重要性。 操作系统的安全性(Operating System Security)是指操作系统采取的一系列措施来保…...
操作系统入门 -- 文件管理
操作系统入门 – 文件管理 1.文件管理概述 1.1 文件系统基本功能 目前,计算机内存的容量依然有限,并且其特性决定了数据无法长时间保存,因此把执行的数据以文件形式保存在外存中,等到需要使用时再调入内存。所以,操…...
由浅入深,走进深度学习(2)
今天分享的学习内容主要就是神经网络里面的知识啦,用到的框架就是torch 在这里我也是对自己做一个学习记录,如果不符合大家的口味,大家划走就可以啦 可能没有什么文字或者原理上的讲解,基本上都是代码,但是我还是想说…...

【Python Tips】创建自己的函数包并安装进Anaconda,像引入标准包一样直接import导入
目录 一、引言 二、方法步骤 步骤一:创建包目录结构 步骤二:配置__init__.py文件 步骤三:文件夹外配置setup.py文件 步骤四:终端Pip安装 三、结尾 一、引言 在编写项目代码的时候,有些自定义功能的函数是可以复用的。…...

【Python机器学习实战】 | 基于支持向量机(Support Vector Machine, SVM)进行分类和回归任务分析
🎩 欢迎来到技术探索的奇幻世界👨💻 📜 个人主页:一伦明悦-CSDN博客 ✍🏻 作者简介: C软件开发、Python机器学习爱好者 🗣️ 互动与支持:💬评论 &…...

备份和还原
stai和dnta snat:源地址转换 内网---外网 内网ip转换成可以访问外网的ip 内网的多个主机可以使用一个有效的公网ip地址访问外部网络 DNAT:目的地址转发 外部用户,可以通过一个公网地址访问服务内部的私网服务。 私网的ip和公网ip做一个…...
Java数组的初始化方法
Java数组的初始化方法 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!在Java编程中,数组是一种非常基础也非常重要的数据结构,它能够存储…...
通过分离有色和无色pdf页面减少打印费
前言 该工具是我认识的一位中科大的大佬在本科毕业的时候做的一个小工具,去打印店打印全彩的毕业论文的话会比较贵,他想到有没有一种方案可以实现有彩色页面的pdf和没有彩色页面的pdf分开打印,前者打印彩色,后者打印黑白…...

c语言--指针
前言 欢迎来到我的博客 个人主页:北岭敲键盘的荒漠猫-CSDN博客 本文整理c语言中指针的相关知识点。 指针概念 指针存储的就是数据的地址。 直观理解: 李华家是北洋路130号1单元101 用变量处理数据: 我们去李华家拿数据。 用指针处理数据: 我们去北洋路130号1单元101拿数据…...

python-九九乘法表(对齐式1)
[题目描述] 输出九九乘法表,输出格式见样例。输入格式: 无输出格式: 输出乘法表,对齐方式见样例输出。样例输入 无样例输出 来源/分类(难度系数:一星) 完整代码展示: #对齐式1 a[] …...
thinkphp单独为某个接口设置缓存
参考 官方文档 $this->request->cache(__URL__,600);只需要在接口方法的开头添加这个代码即可...

OpenCV视觉--视频人脸微笑检测(超详细,附带检测资源)
目录 概述 具体实现 1.加载分类器 2.打开摄像头并识别人脸 3.处理人脸并检测是否微笑 效果 总结 概述 OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉和机器学习库,广泛应用于图像处理和视频分析等领…...

docker 搭建 AI大数据模型 --- 使用GPU
docker 搭建 AI大数据模型 — 使用GPU方式 搭建本地大模型,最简单的方法!效果直逼GPT 服务器GPU系统HP580 G8P40Rocky9.2 安装程序AnythingLLM前端界面Open WebUIChatOllamaollama 一、AnythingLLM 介绍 AnythingLLM 是 Mintplex Labs Inc. 开发的一…...

面向对象, 常用类, 集合, 异常, JDBC, mysql数据库 复习
1.面向对象 (1)面向过程和面向对象 ● 面向过程的程序设计思想 (procedure -Oriented Programming),简称POP ● 关注的焦点是过程:过程就是操作数据的步骤。如果某个过程的实现代码重复出 现,那么就可…...
js取数组最大值之Math.max、Math.max.apply
js取数组最大值之Math.max、Math.max.apply Math.maxMath.max.applyapply()第一个参数为什么可以是null 最小值同理 Math.max Math.max(n1,n2,n3,…,nX) 支持传递多个参数,带有较大的值的那个数 Math.max(2,5,3,6,2,4,2,15,9,6,0,1)Math.max.apply apply() 语法&a…...
各种中间件的安装
文章目录 20232306mysql的wondows安装 2023 2306 mysql的wondows安装 常用mysql教程 springboot整合druid连接池SpringBoot配置Druid连接池 mysql的wondows安装 MySQL学习笔记 01、MySQL安装 这个是安装的具体思路 win10 安装 mysql 5.7 msi版的教程图文详解 这个是安装的…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...

LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...

STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...