搜索
查看
编辑修改
首页
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
自然语言处理课程总结_CodingPark编程公园_自然语言处理 课程报告
2
C++:round函数的用法_c++ round
3
如何把C盘下用户的中文用户名改成英文用户名_c盘用户名字怎么改成英文
4
【话题】开源大模型与闭源带模型你更看好哪一方
5
python IDLE的下载及安装_idle下载官网
6
mysql中if在oracle怎么用_Oracle的NVL()函数和MySQL中的IfNull()函数
7
YOLOv5-v1-Chinese-Comment: 中文注释版YOLOv5,让目标检测更易理解
8
2023 hnust 湖南科技大学 大三下 人工智能导论课程 期中考试复习笔记_已知一个完善的符号系统,能执行下列6种功能
9
解决spark运行中ERROR Shell:Failed to locate the winutils binary in the hadoop binary path的问题_error shell: failed
10
Vue+ElementUI实现表单动态渲染、可视化配置的方法
当前位置:
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
GIT
- 拉取其他仓库的某个
分支
的
代码
_
git
将
两个
代码
仓中
同名
分支
下的不同
代码
提去出来...
https://blog.csdn.net/weixin
_
33901926/article/details/914504...
赞
踩
article
idea
操作
git
远程回滚
到
某个
提交
节点或某个
版本
_
idea
git
回退
到
某个
commit
...
场景:同个项目同时开发两个
版本
分支,不小心将a
版本
代码
提交
到
b
版本
,想要将代码会滚
到
提交
前。解决步骤:通过在网上搜索答案...
赞
踩
article
tensorflow
-
gpu
2.6
.0版本安装教程_
pip
install
tensorflow
-...
2.检查完cuda之后,进入https://developer.nvidia.com/cuda-toolkit-arch...
赞
踩
article
SSH
:关键组件
Kex
,
HostKey
,
HMAC
算法及其用途_
sshhostkey
有啥用...
密钥交换是
SSH
连接建立过程中的第一步,其目的是安全地在客户端和服务器之间协商一个共享的会话密钥。这个会话密钥将用于加密...
赞
踩
article
git
fetch
理解...
git
fetch
是从远程分支拉取代码。
fetch
结合merge一起用,
git
fetch
+
git
merge =...
赞
踩
article
AI:
机器
学习
的
正则
化
(
Regularization
)_.什么是
正则
化
,并说明在
机器
学习
模型
中使用...
机器
学习
之
正则
化
(
Regularization
)1.参数
正则
化
1.1 L2
Regularization
(Ridge ...
赞
踩
article
在
Idea
里如何实现
Git
项目
回滚
_
idea
git
rollback
...
首先我们要
回滚
的项目右键,如下:然后,这里就是你提交和更新的记录选择你要
回滚
的地方,然后右键 Capy Revision...
赞
踩
article
梳理一下
TensorFlow
的
环境
配置
和
Tensorflow
-
gpu
的
环境
配置
_
配置
tensorfl...
华为云镜像源:https://mirrors.huaweicloud.com/repository/pypi/simpl...
赞
踩
article
efficient
_
global
_
pointer
_
import
efficient
global
poi...
(添加参数return_offsets_mapping=True)多生成一个输出用来得到编码前后token的位置。2、(...
赞
踩
article
AtomGit
教程 |
v0.8
.0版本震撼
升级
,11大
功能
抢先看!_
atomgit
pages
...
目前,
AtomGit
不仅提供了全站和仓库内部的代码搜索,并且支持多语言的识别与筛选
功能
,极大地便利了开发者快速定位所需的...
赞
踩
article
基于
PPO
梯度优化、AC框架的
强化
学习
——离散
动作
怎么用
_
ppo
处理离散
动作
...
【
强化
学习
】⚠️手把手带你走进
强化
学习
2⚠️ OPP 算法实现月球登陆器 (PyTorch 版)
_
我是小白呀的博客-C...
赞
踩
article
git
和
git
hub入门实践(2)
:
基本操作
_
git
puttk
生成
...
这篇博文我们将一起完成一次从本地仓库修改代码、提交并推送到远程仓库的操作。Git 本地仓库有三大区域
:
工作区、暂存区、版...
赞
踩
article
拉取
代码
到
本地
git
pull
和
git
clone
的
区别_
clone
和
pull
的
区别...
1. 所以首先要连接远程仓库,前提你得先有个
本地
仓库存放,如果没有先创建。4. 现在,空白仓库可以直接使用。3.显示
本地
...
赞
踩
article
【在
实习期
的
快乐生活】给
hdl
_
localization
加上GPS
_
hdl
-
localization
...
前期准备GNSS RTK需要输出航向角有关数据,经过驱动发布/heading,航向角与RTK设备输出
的
协议有关。以GSV...
赞
踩
article
权重
矩阵
最小
路径
_
动态
规划
(
矩阵
路径
)---
矩阵
的
最小
路径
和...
矩阵
的
最小
路径
和[[1,3,1],[1,5,1],[4,2,1]]Given the above grid map, r...
赞
踩
article
毕业设计
基于ssm
图书馆
借阅
管理系统
_
图书馆
管理系统
毕业设计
...
1.1课题背景及意义网络的快速发展从根本上更改了世界各组织的管理方式,自二十世纪九十年代开始,我国的政府、企事业等单位就...
赞
踩
article
确定
权重
的
方法
总结(部分)...
背景介绍在实际工作中,由于不同影响因子
的
影响程度不同,往往不能将所有
的
指标统一对待,因此要将不同
的
指标赋予不同
的
权重
。注...
赞
踩
article
将项目
代码
上
传
到
github
_
上
传
代码
到
github
...
该文章主要从
上
传
代码
步骤讲起,关于git下载和其环境配置没有涉及到。_
上
传
代码
到
github
上
传
代码
到
github
...
赞
踩
article
提交
代码
学习_每天写
代码
前
git
pull
...
1、
git
中向远程仓库中
提交
代码
时一定要先
pull
再push,本地
代码
进行commit后,仓库不会将本地
代码
与远程仓库的...
赞
踩
article
DolphinScheduler
PMC
Chair
代立冬入选 2021
中国
开源
先锋 33
人
之...
#前言“
开源
”是 2021
中国
技术发展的年度热词,越来越多
人
关注
开源
、贡献
开源
。在本土,“
开源
”作为国家战略被首次写入...
赞
踩
相关标签
git
tensorflow
深度学习
人工智能
ssh
运维
git fetch
git fetch 理解
机器学习
正则化
Regularzation
python
servlet
pytorch
迁移学习
github
定位
自动驾驶
权重矩阵最小路径
课程设计
oracle
数据库