结合现有分布式系统的数据一致性思考

背景

我们项目本身分成了多套系统,但数据上有要求一致性的地方(比如订单状态,通俗点讲就是系统A更新了订单状态为状态一,那么系统B也需要把相同订单的订单状态更新成状态一,这样可以让我们不管是读系统A还是系统B的同一个订单的状态,都可以读出相同的状态数据)。

最原始的伪代码大概为:

sysA.db.transaction.begin();
var success = sysA.db.transaction.updateOrderStatus();
if(!success){sysA.db.transaction.rollback();return;
}success = httpclient.post(sysB.url);
if(!success){sysA.db.transaction.rollback();return;
}sysA.db.transaction.commit();

看了这个代码后,大家应该知道这里有个问题是调用系统B接口,可能出现网络或超时等问题,所以你是不知道系统B是执行成功了还是失败,如果他是执行成功了的,那么系统A回滚了就出问题了,因为两边数据就不一致了。

那么基于CAP理论的实现版BASE,我们采用数据最终一致方案。关于CAP跟BASE,大家可以参考这里

然后我这里参考了个别文章跟同事想法,思考了其中两个解决方案

简单解决方案一

异步任务处理,由原来同步调用B系统变为异步调用。

  1. 系统A先写数据库更新订单状态,然后在本地同时新建一个任务(任务初始状态为待执行),当调用B系统接口完成之后该任务改为已经执行,修改订单状态跟建立任务需要在一个数据库事务下。

  2. 后台定时脚本来执行待执行状态的任务。

  3. 如果异步调用系统B接口返回失败,则需要对之前订单状态更新进行回退。

  4. 如果异步调用系统B接口遇到网络问题或者超时,则考虑重试机制,注意重试机制要避免重复提交,可采取在系统A重试前确认和在系统B保证接口的幂等。

想了一下,这个方案有个问题就是状态可能发生了多次改变,如果先后顺序出现问题,那么将造成订单状态更新错误,所以就得有个队列来保存订单状态的多次先后顺序更新才行,于是有了方案二

简单解决方案二

引入消息队列,相当于对方案一的升级版,新建立任务变成新建立消息

  1. 系统A为消息生产者,系统B为消息消费者。

  2. 生产者系统A接收到用户请求,先写数据库更新订单状态,然后写一条更新订单状态的消息到消息队列,并且要新建一张消息状态表用于记录消息的执行状态(初始状态为待执行),以上三个操作要在同一个本地事务中进行,这个是容易忽略的地方。其实也可以在业务订单表增加一个字段用来表示消息执行状态。当然对于这个订单的后续业务操作,只有在这个消息执行成功后才能继续,也就是有一个因果先后关系在里面才行。

  3. 消费者系统B取出一条消息,进行相同订单的状态更新,处理完成后需要告诉系统A消息执行结果,是成功还是失败。这里简单说下失败的情况,第一次失败的话,系统B就可以进入重试逻辑,重试多次如果还是失败才需要告诉系统A我这边最终执行失败了,你可能要采取点措施才行,比如回滚呀,还是什么的。

总结

  1. 分布式系统以基本可用跟快速高效的最终一致为目标

  2. 远程RPC调用中的网络跟硬件等问题是造成一致性的主因,异步解耦加消息队列等方式可作为分布式系统满足最终一致性的一个比较好的方案。

参考:

  1. https://www.cnblogs.com/kerwing/p/9098893.html 主要参考了此文,然后做了一些自己的理解跟修改

  2. https://www.cnblogs.com/frankltf/p/10374662.html

  3. https://www.cnblogs.com/hzmark/p/consistency_model.html

联系作者请添加微信号:sutong324,并注明:来自cnblogs

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

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

相关文章

[蓝桥杯2019初赛]特别数的和-枚举

题目描述 小明对数位中含有2、0、1、9 的数字很感兴趣(不包括前导0) 在1到40中这样的数包括1、2、9、10 至32、39 和40,共28 个,他们的和是574。 请问,在1到n 中,所有这样的数的和是多少? 输入…

wordList01

wordList one 如果存在什么问题请批评指正!谢谢

《ASP.NET Core 微服务实战》-- 读书笔记(第4章)

第 4 章 后端服务现实中的服务不可能处于真空之中,大多数服务都需要与其他服务通信才能完成功能。我们将这些支持性服务称为后端服务,接下来我们将通过创建一个新的服务并修改之前的团队服务与这个服务通信,以探索如何创建并消费后端服务。微…

WordList02

WordList 2 如果存在什么问题欢迎批评指正!谢谢!

CentOS7 安装 Jenkins( 构建 Vue 和 dotNET Core )

之前的自动构建工具 Jenkins 是部署在公司内网的 Windows 服务器上,现在武汉处于非常时期,兄弟们都在家自我隔离,为了远程提交的代码能自动构建,需要在外网的 CentOS 服务器上搭建 Jenkins 环境来进行构建工作。目的产品采用前后端…

shell(希尔排序)

shell&#xff08;希尔排序&#xff09; 原理:参考趣学数据结构 代码&#xff1a; #include<stdio.h> #include<stdlib.h> void shellInsert(int b[],int dk,int length) {//希尔排序以dk的增量插入int j;for (int i 1 dk; i < length-1; i) {b[0] b[i];//哨…

[蓝桥杯2019初赛]等差数列-数列

解题思路: 给你n个数&#xff0c;是某个等差数列的一部分&#xff0c;问该等差数列最小有几项&#xff1f;&#xff1a;((最大数−最小数)/d)1((最大数-最小数)/d)1((最大数−最小数)/d)1,其中d是该等差数列所有&#xff08;所有已知数与最小数差值&#xff09;的最大公因数&am…

Dynatrace成功扩展kubernetes全栈可观察性

软件情报公司Dynatrace&#xff08;NYSE&#xff1a;DT&#xff09;在Perform 2020会议上宣布了对Kubernetes支持的新增强功能。Dynatrace可解释的AI引擎DavisTM现在自动获取其他Kubernetes事件和指标&#xff0c;使其能够在整个Kubernetes集群&#xff0c;容器和工作负载的堆栈…

wordList3

wordList3 如果存在什么问题&#xff0c;欢迎批评指正&#xff01;谢谢&#xff01;

[蓝桥杯2019初赛]矩形切割-找规律

代码如下&#xff1a; #include <iostream> using namespace std;int main() {int a, b;int ans 1;cin >> a >> b;while (1) {if (a 1 && b 1 || a b)break;if ( a > b) {int c b;b a;a c;}b b - a;ans;}cout << ans << end…

K8S水平伸缩器 - 自动伸缩微服务实例数量

作者&#xff1a;justmine头条号&#xff1a;大数据达摩院微信公众号&#xff1a;大数据处理系统创作不易&#xff0c;在满足创作共用版权协议的基础上可以转载&#xff0c;但请以超链接形式注明出处。为了方便大家阅读&#xff0c;可以关注头条号或微信公众号&#xff0c;后续…

[蓝桥杯2019初赛]质数-质数筛or 水题

法一&#xff1a; 代码如下&#xff1a; #include <iostream> #include <cmath> using namespace std;bool check(int x) {for (int i 2; i < sqrt(x); i)if (x % i 0)return false;return true; }int main() {int n;int ans 0;for (int i 2; i; i) {if (c…

SqlServer 利用游标批量更新数据

SqlServer 利用游标批量更新数据Intro游标在有时候会很有用&#xff0c;在更新一部分不多的数据时&#xff0c;可以很方便的更新数据&#xff0c;不需要再写一个小工具来做了&#xff0c;直接写 SQL 就可以了Sample下面来看一个实际示例&#xff1a;-- 声明字段变量 DECLARE Re…

math:线性代数之行列式

math&#xff1a;线性代数之行列式 提供解题的方法总结 如果存在什么问题&#xff0c;欢迎批评指正&#xff01;谢谢!

[蓝桥杯2019初赛]旋转-找规律

代码如下&#xff1a; #include <iostream> using namespace std; const int N 110; int a[N][N];int main() {int n, m;cin >> n >> m;for (int i 1; i < n; i)for (int j 1; j < m; j)cin >> a[i][j];for (int i 1; i < m; i){for (in…

《ASP.NET Core 微服务实战》-- 读书笔记(第5章)

第 5 章 创建数据服务选择一种数据存储由于我坚持要尽可能的跨平台&#xff0c;所以我决定选用 Postgres&#xff0c;而不用 SQL Server 以照顾 Linux 或 Mac 电脑的读者构建 Postgres 仓储在本节&#xff0c;我们要升级位置服务让它使用 Postgres为了完成这一过程&#xff0c;…

数据结构-拓扑排序

拓扑排序&#xff1a; 因为上一篇有点小问题&#xff08;Stack.base Stack.top 写成了 Stack.base Stack.base&#xff09;导致死循环&#xff0c;最后导致内存溢出&#xff0c;地址访问冲突 参考上一篇的链接&#xff1a; https://blog.csdn.net/qq_43552933/article/deta…

[蓝桥杯2018初赛]分数-找规律

题目描述 1/1 1/2 1/4 1/8 1/16 … 每项是前一项的一半&#xff0c;如果一共有20项,求这个和是多少&#xff0c;结果用分数表示出来。 类似&#xff1a;3/2当然&#xff0c;这只是加了前2项而已。分子分母要求互质。 代码如下&#xff1a; #include <iostream> u…

腾飞答不忘初心的三个问题

去年的时候有同学在微信上问了我3个问题&#xff0c;我觉得非常有代表性&#xff0c;当时没有回答。主要是通过简短的语言无法全面表述可能会产生歧义&#xff0c;所以决定专门写一篇文章来表达一下我的想法&#xff0c;需要说明的是以下内容只是以我个人的经验给大家一些参考。…

wordList04

wordList04 如果存在什么问题&#xff0c;欢迎批评指正&#xff01;谢谢&#xff01;