工程中实践的微服务设计模式

大家好,我是 方圆。最近在读《微服务架构设计模式》,开始的时候我非常的好奇,因为在我印象中,设计模式是常说的那23种设计模式,而微服务的设计模式又是什么呢?这个问题也留给大家,在文末我会附上我对这个问题的理解。本次文章的内容主要是工作中对微服务设计模式的应用,希望能对大家有所启发。

事务发件箱模式

事务发件箱模式:将消息保存在数据库 “发件箱”表 作为事务的一部分

policy 为处理投保的微服务,以投保事务为例:

在这里插入图片描述
如上图所示,在投保过程中有4步操作(注意持久化结算任务(Task)A的操作),这个过程便是事务发件箱模式的体现,为什么说它是事务发件箱模式呢?

  1. Task 表中持久化的消息任务最终会被发送到 MQ 中,所以它是发件箱
  2. 持久化 Task 记录的操作被包含在事务中,所以称它为事务发件箱

Task 记录中保存的消息体是通过另一个服务 service-job 轮询扫描初始化状态的任务,并将其发送到 MQ 的,发送成功后任务修改为完成状态,这种方式被称为事务性发件箱模式中的轮询发布数据模式

这种设计模式有一个弊端:随着数据量不断增大,经常轮询数据库可能造成昂贵的开销。在我们的系统中采用了两种措施进行优化:

  • 分库分表:以空间换时间,避免单表数据量过大造成的开销
  • 将完成状态的任务进行“数据结转”的设计:任务先保存在 Task 表中,被执行完成后被归档到 TaskRecord 表中

此外还有一种更加高效但是开发稍复杂的方式:拖尾数据库日志模式

拖尾数据库日志模式

在这里插入图片描述
数据库的每次更新都对应着一条数据库事务日志,通过事务日志挖掘器读取事务日志,并将每条与消息有关的记录发送给消息代理(开源框架可参考:Github: debezium,可以将MySQL的binlog读取到Kafka中),但是这种方法的弊端是需要在开发上做一些努力,因为需要监听数据库事务日志和调用数据库底层相关的API。

相信“邮递员”

工程实践中,还有一种没有采用事务发件箱模式来保证数据一致性的方法:在事务中先持久化完成状态的任务,随后直接将消息发送给消息队列,如果消息发送失败,捕获异常并将任务修改成初始化状态,随后依赖 service-job 服务进行补偿:即将初始化状态的任务发送给 MQ。我们还是以投保的过程为例,如下代码所示:

// 1. 持久化保单数据
savePolicy();
// 2. 持久化保单明细数据
savePolicyDetail();
// 3. RPC 调用投保接口
rpcPolicy();
// 4. 持久化完成状态的任务,任务中记录了要发送给MQ的消息体
int num = insertTask(TaskStatus.COMPLETE);
// 5. 如果插入成功了,借助线程池发送消息
if (num > 1) {threadPoolExecutor.execute(() -> {try {mq.send(task.info);} catch(Exception e) {// 发送失败,抛出异常,修改任务状态为初始化状态,依赖 service-job 服务进行补偿updateTask(TaskStatus.INIT);}});
}

这种设计模式默认认为MQ集群始终是高可用的,我将这种设计模式命名为相信“邮递员”。在生产实践中,因为有MQ运维团队在保障MQ集群的高可用,所以这种设计模式也是比较稳定的。


在投退保流程中,涉及不同数据库的修改操作,如保单的持久化、保单状态的修改以及相关结算的推送,要保证这个过程中的数据一致性,那么便不能再依赖ACID本地事务,而是需要使用跨服务的 Saga 设计模式来维护数据一致性。下面我们来介绍两种,分别是协同式Saga编排式Saga

Saga 通过使用异步消息来驱动一系列本地事务,来维护多个服务之间的数据一致性。

协同式Saga

我们先带着 Saga 的概念来看一下投保的流程:

在这里插入图片描述

在这个过程中,Saga的决策和执行顺序分布在Saga的每一个参与方中,并且通过消息交换的方式进行沟通,一个Saga的参与方执行完触发另一个Saga执行,保证数据一致性,这种方式被称为协同式Saga

这种设计模式的优劣如下:

  • 优势:比较简单,服务间松耦合
  • 弊端:比较难理解,因为它没有一个地方定义了Saga的执行流程,Saga的处理逻辑分布在不同的服务中,需要根据代码触发的任务去整理整个流程

为什么没有采用XA来实现分布式事务


XA采用两阶段提交协议实现分布式事务,在事务中的所有参与者都成功时提交,有失败时便回滚。要使用该模式一方面要求所有的事务参与者(数据库或消息代理)满足XA标准,另一方面,它本质上是同步的进程间通讯,同步的通讯机制有一个弊端:它会降低分布式系统的可用性(假如分布式系统中每个服务的可用性为99%,如果服务与服务之间是同步调用的方式:服务必须从另外一个服务获取响应后才能返回它的客户端调用,那么分布式系统的可用性为各个服务可用性的乘积,随着同步交互服务的增加,可用性会随之降低,最大化可用性的方式应该最小化系统间的同步操作量)。所以,一般互联网公司很少采用强一致性的设计,而是采用最终一致性设计(银行可能会使用到强一致性)。此外,XA实现分布式事务需要依赖事务的协调者(如Seata),实现起来相比于上述方式复杂。

编排式Saga

Saga 的另一种实现方式是编排式,编排式 Saga 需要事务的协调者(DTM),全局事务发起人将整个全局事务的编排信息,包括每个步骤的正向操作和反向补偿操作定义好之后,提交给事务协调者(DTM),协调者按步骤异步执行Saga逻辑。

如果投保流程使用编排式Saga的话,投保成功的过程如下:

在这里插入图片描述
编排式Saga的事务定义执行步骤非常灵活,假如我们要在投保失败的情况下做取消结算的补偿逻辑的话,可以自行定义,图示如下:

在这里插入图片描述

这种设计模式的优劣如下:

优势:能够集中流程控制、易于扩展和服务间松耦合,如果服务之间的依赖关系复杂,且业务流程经常变动,使用编排式Saga是合适的
弊端:引入协调者增加了开发复杂性(扩展学习:DTM开源项目文档)


现在我们回到文章开篇的问题:微服务架构设计模式与我们常说的设计模式的区别是什么?

我们常说的设计模式是面向对象的设计模式,它的解决方案元素是类,而微服务设计模式是站在更高维度即系统架构层面的设计模式,它面向的对象是系统中各个服务,解决方案也由相互协作的服务构成的。


巨人的肩膀

  • 《微服务架构设计模式》:第 1 - 4 章

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

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

相关文章

opencv图像处理技术(阈值处理与图像平滑)

进行图像处理时,常常需要对图像进行预处理以提取所需的信息或改善图像质量。阈值处理和图像平滑是两种常见的预处理技术。 阈值处理 阈值处理是一种图像分割技术,其基本思想是将图像中的像素值与一个或多个预先设定的阈值进行比较,根据比较…

【人工智能】猫狗识别

猫狗识别 实验背景 数据集介绍 我们使用CIFAR10数据集。CIFAR10数据集包含60,000张32x32的彩色图片,10个类别,每个类包含6,000张。其中50,000张图片作为训练集,10000张作为验证集。这次我们只对其中的猫和狗两类进行预测。 图 1 CIFAR10 数据…

Windows11配置VUE开发环境

目录 一、按照nodejs二、命令安装npm cache clean --forcenpm install -g vue/clinpm install npm -gnpm install webpacknpm install vue-cli -g与npm install -g vue/cli区别npm install -g cnpm --registryhttps://registry.npm.taobao.orgnpm i yarn -g --verbosenpm i -g …

网络与并发编程(一)

并发编程介绍_串行_并行_并发的区别 串行、并行与并发的区别 串行(serial):一个CPU上,按顺序完成多个任务并行(parallelism):指的是任务数小于等于cpu核数,即任务真的是一起执行的并发(concurrency):一个CPU采用时间…

IDEA 导出jar无法执行 错误: 找不到或无法加载主类

1、首先配置正确Project Struct 保证需要引用的jar包库添加到Libraries里,尽管添加到Modules里依然可以测试运行或调试,但导出的jar包会遇到问题。 2、导出jar,方式选择如下 选择”From modules with dependencies" 然后去掉以上“Extr…

手机如何在线制作gif?轻松一键在线操作

现在大家都喜欢使用手机来拍摄记录有趣的事物,但是时间长了手机里的视频越来越多导致手机存储空间不够了,这些视频又不想删除时应该怎么办呢?这个很简单,下面就给大家分享一款不用下载手机就能操作的视频转gif网站-GIF中文网&…

【贪玩巴斯】Mac的M芯片(M1/2...)下载homebrew方法(24年最新且已验证可行)

1. 按照目前广为流传的方法(M1会出现一些问题): 终端输入: /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)" 使用国内镜像下载。 2. 输入后按照要求步骤执行即可&#xff…

k8s单节点部署,容器运行时使用containerd

环境 系统 : entOS Linux release 7.9.2009 (CoreIP:192.168.44.177 硬件要求:控制平面最少需要 2c2g 安装前环境准备 如果是集群部署还需要配置时间同步 关闭防火墙 systemctl disable firewalld关闭selinux setenforce 0sed -i s/SELI…

Vue - 你知道Vue组件中的data为什么是一个函数吗

难度级别:中高级及以上 提问概率:80% 在Vue项目中,App.vue下的每个子组件都会生成一个单独的Vue实例对象,但这些子对象都是通过通过vue.extend方法创建而来的,也就是说我们平时在项目中所定义的Vue组件,都有一个相同的父类对象。这样也就…

JS-PC/MOBILE技巧--PC

一、PC 端网页特效 1、元素偏移量 offset 系列 offset 概述 offset 就是偏移量,使用 offset 系列相关属性可以动态的得到该元素的位置(偏移)、大小等。 获取元素距离带有定位父元素的位置获取元素自身的大小(宽度高度&#xff0…

前端入门(认识HTML,CSS,JavaScript三件套)

目录 前言 HTML(构建) CSS(设计) JavaScript(互动) 总结 相关书籍推荐 前言 前端(Frontend)指的是与用户直接交互的部分,也称为客户端。在网站或者应用程序中&…

特别详细的Spring Cloud 系列教程1:服务注册中心Eureka的启动

Eureka已经被Spring Cloud继承在其子项目spring-cloud-netflix中&#xff0c;搭建Eureka Server的方式还是非常简单的。只需要通过一个独立的maven工程即可搭建Eureka Server。 我们引入spring cloud的依赖和eureka的依赖。 <dependencyManagement><!-- spring clo…

如何成为一名优秀的工程师下

身为工程师&#xff0c;理所当然要重视实践&#xff0c;自然科学不管发展到何时都离不开实验。 电子学本身就是 为了指导工程实践。所以不要谈空洞的理论。现在很多毕业生都面临这样的问题&#xff0c;总是谈一些空洞的理论&#xff0c;甚至错误的但还不以为然的理论。实践可以…

uniapp 密码框的眼睛

效果展示&#xff1a; uniapp input 官网链接&#xff1a;链接 按照官方文档&#xff0c;uni-icon出不来。 通过自己的方法解决了&#xff0c;解决方案如下&#xff1a; 代码&#xff1a; <uni-forms-item name"password"><inputclass"uni-input&quo…

Spring AI 来了,打造Java生态大模型应用开发新框架!

Spring AI 来了&#xff0c;打造Java生态大模型应用开发新框架&#xff01; Spring AI 开发框架设计理念Spring AI 主要功能特性如下 Spring AI 应用开发案例案例一&#xff1a;基于大模型的对话应用开发案例二&#xff1a;RAG 检索增强应用开发案例三&#xff1a;Function Cal…

15-1-Flex布局

个人主页&#xff1a;学习前端的小z 个人专栏&#xff1a;HTML5和CSS3悦读 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结&#xff0c;欢迎大家在评论区交流讨论&#xff01; 文章目录 Flex布局1 Flex容器和Flex项目2 Flex 容器属性2.1 主轴的方向2.2 主轴对齐方式…

vscode-插件开发-hello world-创建初始模板

参考vscode官方示例&#xff1a;如何创建你的第一个插件开发项目模板的步骤进行了下文操作。 目录 前言1.环境配置全局安装 yo, generator-code 2. 新建一个插件项目模板问题1: F5 按键无法启动launch.json调试(解决)问题1 描述:问题1: 找错误问题1: 可行的解决方案 3. 开发插…

SpringBoot集成Redis快速入门Demo

目录 1. Redis概述 2.下载安装 3. Spring-data-redis概述 4. 快速入门 4.1 创建工程 4.2 导入依赖 4.3 添加配置文件 4.4 添加Redis配置 4.5 添加Redis工具类 4.6 添加测试类 5. Demo下载地址 1. Redis概述 Redis&#xff08;Remote Dictionary Server 远程…

ics-05-攻防世界

题目 点了半天只有设备维护中心能进去 御剑扫一下 找到一个css 没什么用 再点击云平台设备维护中心url发生了变化 设备维护中心http://61.147.171.105:65103/index.php?pageindex试一下php伪协议 php://filter/readconvert.base64-encode/resourceindex.php base64解一下…

华为海思校园招聘-芯片-数字 IC 方向 题目分享——第九套

华为海思校园招聘-芯片-数字 IC 方向 题目分享&#xff08;有参考答案&#xff09;——第九套 部分题目分享&#xff0c;完整版获取&#xff08;WX:didadidadidida313&#xff0c;加我备注&#xff1a;CSDN huawei数字芯片题目&#xff0c;谢绝白嫖哈&#xff09; 单选 1&…