搜索
查看
编辑修改
首页
UNITY
NODEJS
PYTHON
AI
GIT
PHP
GO
CEF3
JAVA
HTML
CSS
搜索
2023面试高手
这个屌丝很懒,什么也没留下!
关注作者
热门标签
jquery
HTML
CSS
PHP
ASP
PYTHON
GO
AI
C
C++
C#
PHOTOSHOP
UNITY
iOS
android
vue
xml
爬虫
SEO
LINUX
WINDOWS
JAVA
MFC
CEF3
CAD
NODEJS
GIT
Pyppeteer
article
热门文章
1
java.lang.IncompatibleClassChangeError异常的正确解决办法,亲测有效,嘿嘿嘿!!!java.lang.IncompatibleClassChangeError异常
2
Python程序员入职后如何做自我介绍,才能让大家记住你_用python做自我介绍
3
算法与数据结构汇总
4
Linux中ssh远程登录系统和远程拷贝_ssh copy
5
基于STM32的物联网智能家居语音控制系统设计_家庭智能语音控制系统 csdn
6
从零开始学自然语言处理-十万字长文带你深入学习自然语言处理全流程_自然语言处理发展 万字长文
7
数据结构与算法----详解二叉树的遍历(迭代、递归)_二叉树层次遍历递归算法
8
Java中的线程安全(同步、锁)及线程通信_java线程安全
9
SQL学习(1)——数据库概念+单表SQL查询+多表SQL查询_用sql server掌握查询建立,单表查询和多表查询
10
Mac环境配置(Java)(附Java8下载地址)_java 8下载地址
当前位置:
article
> 正文
Go微服务: 分布式之通过可靠消息实现最终一致性
作者:2023面试高手 | 2024-06-09 21:47:36
赞
踩
Go微服务: 分布式之通过可靠消息实现最终一致性
通过可靠消息实现最终一致性
可靠消息,就是靠普消息,还是基于之前的这个案例
比如这个订单服务,无论你是先发送消息,还是先新建订单,它其实都是发送的不可靠消息
就是说如果这个消息,像mysql事务那样,只要订单服务不确认,下游就没办法消费
如果你这个订单服务挂了,就可以取消这个消息,就不用做这个本地消息表了
本地消息表,要有一个这个循环的这么一个查询,高并发的时候,你本地的数据库本身压力就大
再弄这么一个查询,一直循环的查,它这个压力也不小,现在看一下基于事务消息,也称为可靠消息
生产者就可以理解为这个订单服务,消费者就可以理解为积分服务,还有库存服务
先看第一个,生产者先发一个
半消息
给消息队列,消息队列就回我这个半消息成功的信息
这是一个半消息,然后拿到这个半消息成功的结果之后,我们往数据库里写一个Transaction事务
我们就把本地事务执行了,执行之后,也就是到了第4步, 成功情况下就是确认这个半消息
只要到第4步这个commit成功了,消费者就可以消费了,因为你的这个消息已经在这个消息队列中了
这个解决方式是解决了只要我们能发出去的这个消息就是可靠的,只要能提交的消息,本地消息就一定是成功的
因为你本地事务都已经执行成功了,先发半消息,消息队列回给我,回给我之后,我就能收到了,说明已经成功了
然后这个时候你就开始干你本地的事儿,比如订单生产者自己开始建订单,建订单产品表,这都是你的事
我本地能成功了之后,1,2,3步是为了能让消费者成功消费的准备工作
这个思路就是说只要一提交,那我本地这边全部ok, 然后我这个消息队列, 肯定能保证我我的最终一致性
如果在3之前出错,那不会做事务,那相当于准备工作没做好,那下游也不会做相应的这个事情
同时,我们还要思考,有没有其他方面的情况会导致问题
比如,更复杂的网络传输问题,别人的服务宕机了或有bug了
因为微服务在开发的时候,每个小组可以时刻发布自己的服务,它不受控制
如果上述分布式服务出问题了,消息队列也会有一个回查事务消息状态的机制
我会问你这个生产者,哎,你这个状态是啥?然后生产者就会查询这个本地事务状态
第5步和第6步,就是又一次为这个返回事务状态做commit和rollback,就是为下一步的工作做准备
就是消息队列,不知道你这个消息要不要投递,也不能知道别人的状态是什么样的
那消息队列就会问这个生产者,你这个消息事务是啥状态,在第6步得到查询的事务状态是commit
那我消息队列就commit消息投递,一旦消息投递了,这个消费者就可以进行消费了
假如说,返回的这个事务状态是rollback,消息队列就可以把消息扔了
在这整个链路里,有成功的,让消费者消费消息;也有失败,让这个消息队列去丢弃消息
还有中间状态,就是说我不确定这个事务是不是正确的?那询问还是有结果的,就是 commit 或 rollback
其实我们说走到第5步,第6步,还有第7步的时候,他就可以再一次确认我们的消息是否要投递还是丢弃
到这里,一直没有看到说有锁的存在,在高并发的情况下,消息队列就保证了我们最终的一致性
就是说锁的存在,它一定是和高并发是这个对立的,我们尽量不要用锁的方式去考虑我们的并发
积分和库存业务场景的对比
再回过头来看一下这个模型,如果你的生产者是订单,而消费者是库存的话
如果库存不足,消费者是库存服务,库存不足,虽然成功的发送了到这个RocketMQ里
但是库存没有办法成功消费这条消息,这个和其他业务形态上是不一样的
比如订单服务,可以说是送积分,从技术角度来说,积分是没有上限的
还有一种形态,就是我们说发短信,你成功的购买了某某产品等等
这种业务形态, 你的生产者只要把消息放到了消息队列, 消息队列一定是可以保障的
就是说你消息队列是集群吧,你在不挂的情况下,是一定能送达到消费者应用队列里的
比如说, 积分服务,短信服务,你这边已经是commit了
无论你是在第4步commit的,还是说第7步commit的下游是一定能消费到的
但是库存服务不一样,如果库存不足了,你这边又没办法返回
左边是库存服务和订单服务,右边是消息队列
从正向来说,如果服务的提供方发送消息到这个消息队列,也就是生产者发送消息到消息队列
只要消息队列集群不挂,那么我们的消费者是一定能收到这个消息的
就是实现最终的一致性对于积分服务,短信服务的使用都是没有问题的
因为积分理论上是无上限的,我们的短信是一定能发上去的,只要你短信账户里,有足够的余额
但是当库存为零的时候,你的这个消息队列仍然收到了我们发送成功的消息
但下游库存服务是没有办法消费成功的,我们不可能凭空多出来这么多库存
让你去消费,因为没有那么多库存,我们又不能把这个消息队列成功投递库存不足的消息
再返回给这个生产者,这个是不可能的,所以,我们能不能先发送一个
归还库存的半消息
这个半消息, 对于库存服务来说, 它是见不到的,我们发完半消息之后
去调用扣减库存的Srv服务,这就是一个Grpc的这么一个调用,先看这个返回失败的情况
如果调用库存失败了,这个时候返回一个rollback,因为一开始就是调用的是归还
那你这个时候就调用rollback,如果我们库存执行失败了,那说明我们库存这个数据是没有变的
既然你库存调用是失败,订单就不会创建, 因为我本地这个数据库就不会变
那么我们两边的这个数据都没变,这个业务也是可以接受的
就是说没有造成数据不一致,那你就不要给我发这个消息来告诉我,你要去归还库存了
那我们直接rollback这个消息,然后这个消息队列, 就可以把这个归还库存的消息给它扔掉了
扔掉之后,看左边这一边就没问题了,数据都没变
你执行失败了,我这边又没执行,或者说,这两边的数据都保持一致,这就是OK的
好,我们再看下一张执行成功的图,看我们订单服务发送一个半消息
然后调用了Grpc扣减那个库存,然后它成功了
成功之后, 我们就会执行这个本地 mysql 事务服务, 其实它可能成功,也可能失败
因为我们如果在微服务里, 由于网络原因或宕机,Bug,停电等各种问题
它都可能导致一个服务的运行失败
如果我们先说这个执行本地mysql事务成功,在第4步成功,执行rollback
还是从数据的角度来看,库存扣减成功,订单执行成功,我们本地也执行成功
那就是说我们两边数据都改变了,这个业务上也是可以接受的
订单生成成功了,库存也扣减了,那就相当于交易成功
那你就不要给我发送这个归还库存的半消息了,所以是 rollback这个半消息
然后,我们把这个消息就扔掉了
那我们再看看,如果第4步执行失败了,就是说我们有任何情况
订单服务有bug,断电或者其他场景,执行失败,那就执行一个commit
因为订单执行失败了,相当于订单数据没有变,那你的库存现在是变了
因为之前第三步已经执行成功了,那这个时候就要告诉库存,说给我扣减了,因为我执行失败了
失败以后,提交一个commit之后,然后,这个库存服务就可以监听到这个消息队列里
因为它 commit 了嘛,这个消息就能看到了,订阅了这个消息之后,就能去归还库存了
如果你这个订单服务,还有一些其他问题,怎么办?其实这个消息队列还提供一种机制
就是回查这个消息,比如说我现在不确定你这个是要提交还是rollback
这个回查机制,就查这个订单的服务,那你还去你这个本地事务的数据库库里去捞数据
你捞对了,就rollback,捞错了,还是commit, 你commit之后
我还是能调用到这个库存服务,然后你再给我归还
这张图就是看到了为了保持这个数据的一致性,我们这边整个业务流程的保证就是这样了
再看上面这张图,还有问题,是在原来的基础上增加了第8条发送延迟消息和监听延迟消息。
就是说我这个库存有一百个,我这个用户买完以后,就是不支付
如果他一周不支付或者一个月不支付,你的库存永远不释放,别人永远买不了
那不就把这个商城的库存给锁死了
当我库存执行成功,这个本地的事务也执行成功的时候,我就把它发送一条延迟消息。
假如我们规定半个小时,时间一到,这个延迟消息就会投递
然后,我们就会根据这个消息去看,这个订单是 支付成功了,还是支付失败了
如果是未支付或者是支付失败都可以,如果你执行失败了,那我就归还库存
因为对商城来说,如果没收到钱,那我就归还库存,半个小时之后,仍然其他的用户就可以买
这样就完美的解决了库存,订单和这个订单下单成功后不支付的这么一个场景
这里的核心重点是:在一开始发送了一个归还库存的半消息
执行commit和rollback的情况是反着来的
声明:
本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:
https://www.wpsshop.cn/w/2023面试高手/article/detail/695908
推荐阅读
article
Flink
专题七:
Flink
中
广播
流
之
BroadcastStream
_
flink
广播
流
...
由于工作需要最近学习
flink
现记录下
Flink
介绍和实际使用过程这是
flink
系列的第七篇文章
Flink
中
广播
流
之B...
赞
踩
article
点云
的
实例
分割
和
语义
分割
_
点云
实例
分割
...
SGPN [CVPR 2018]:
点云
的
实例
分割
与物体检测。(SGPN: Similarity Group Propos...
赞
踩
article
【论文翻译】A
Benchmark
and a
Baseline
for
Robust
Multi-...
【论文翻译】A
Benchmark
and a
Baseline
for
Robust
Multi-
view
Depth...
赞
踩
article
hadoop
安装
教程
(一次填完所有
的
坑)_csdn
hadoop
下载
安装
教程
...
本文主要讲解了如何
安装
hadoop
、使用
hadoop
的
命令及遇到
的
问题解决,希望能帮助到大家,谢谢_csdn
hadoop
...
赞
踩
article
推荐
一款
高效
简洁的开源
任务
管理工具
——
Sleek
...
推荐
一款
高效
简洁的开源
任务
管理工具
——
Sleek
项目地址:https://gitcode.com/ransome1/...
赞
踩
article
前端
状态
管理
请三思...
最近我开始思考React应用的
状态
管理
。我已经取得一些有趣的结论,并且在这篇文章里我会向你展示我们所谓的
状态
管理
并不是真...
赞
踩
article
基于
FPGA
的现代
数字电路
设计
_基于
fpga
的
数字电路
综合性实验
设计
...
专业名词PAL-宏单元PLD (Programable Logic Device) CPLD LAB(Logic Arr...
赞
踩
article
ssh
方式克隆
GitHub
repo
_
通过
ssh
克隆
repo
...
通过
这个命令返回的结果,可以确定是服务器端的问题,还是自己本地的SSH客户端配置问题。这有助于针对性地解决SSH无法连接...
赞
踩
article
L298N
模块
详细使用教程...
L298是15脚Multiwatt封装的
L298N
,内部包含4通道逻辑驱动电路;是一种二相和四相电机的专用驱动器,即内含...
赞
踩
article
Git:
本地
分支
和
远程
分支
建立
追踪
关系
的三种方式 在
本地
创建
本地
分支
去追踪
远程
分支
_
zenme1
本地
...
一、
建立
追踪
关系
的三种方式1.1 手动
建立
追踪
关系
$ git branch --set-upstream-to=<
远程
主...
赞
踩
article
moocpython
答案
_
中国大学
慕课
moocPython
编程基础全套
答案
...
参考
答案
如下柴油发动机滤清器或输油泵滤网堵塞,中国低压油路工作不受影响。图形的尺寸按其作用分为定形尺寸、大学
答案
定位尺寸...
赞
踩
article
MATLAB
的贪婪算
法
优化
tsp
问题
(附完整代码)_知道
距离
矩阵如何用节约
法
求解
tsp
问题
matla...
MATLAB
的贪婪算
法
优化
tsp
问题
(附完整代码)_知道
距离
矩阵如何用节约
法
求解
tsp
问题
matlab
知道
距离
矩阵如何用...
赞
踩
article
DDR
详解...
系列文章目录提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加例如:第一章 Python 机器学习入门之p...
赞
踩
article
决策树
算法
及其
python
实例
_
决策树
python
例子...
如果A 为空或者D中样本在A 上取值相同 则将node 标记为叶结点,其类别标记为 D中样本数最多的类;信息增益准则对可...
赞
踩
article
好
说
AI
:一款
多功能
的
AI
助手应用...
AI
聊天
好
说
AI
的
AI
聊天功能采用了先进的自然语言处理技术,能够准确地理解你的意图,并给出合适的回复。无论你是想要什么知...
赞
踩
article
Bishop
模式识别
与机器
学习
读书笔记
_ch1.3 决策论与
信息论
基础_
bishop
这本书讲了什...
信息论
和决策论为机器
学习
模型提供了重要建模思路_
bishop
这本书讲了什么
bishop
这本书讲了什么 ...
赞
踩
article
负载
均衡
的
秘密武器
:
权重
法
算
法
的原理与实现_
负载
均衡
权重
算
法
...
权重
法
算
法
,就像是一枚精心打磨的钥匙,能够打开
负载
均衡
的大门。但是,我们需要明白,这把钥匙并不是万能的,它也有自己的局限...
赞
踩
article
Kafka
原理基本
组件
_
kafka
组件
原理
csdn
...
Kafka
一、
Kafka
是什么
Kafka
是一种高吞吐量的分布式发布--订阅消息系统。它可以处理消费者规模的网站中的所有...
赞
踩
article
SpringCloud
Sleuth
+
Zipkin
分布式
链路追踪实践_
sleuth
+zinki...
Spring Cloud
Sleuth
是 Spring Cloud 中的一个组件,它能够帮助开发者完成
分布式
系统中的跟...
赞
踩
article
尝新
学术
版
ChatGPT
!
中科院
chatGPT
学术
优化
_
中科院
gpt
学术
优化
国内不能用...
1,安装依赖 配置 requirements. txt 文件的时候报错,提示找不到requirements. txt 文...
赞
踩
相关标签
flink
java
大数据
datastream
点云实例分割
点云语义分割
MVS
深度估计
基准
基线模型
hadoop
hdfs
前端
ui
javascript
ViewUI
fpga
ssh
github
单片机
stm32
物联网
git
moocpython答案