背景

我们项目本身分成了多套系统,但数据上有要求一致性的地方(比如订单状态,通俗点讲就是系统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

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

  1. 关于分布式系统的数据一致性问题(一)

    最近写了一个关于 铁道部购票系统的若干文章 铁道部新客票系统的设计(一) 铁道部新客票系统的设计(二) 铁道部新客票系统的设计(三) 正好遇到一个博友,咨询了一个问题,这个问题正好可以作为分布式系统的 ...

  2. 关于分布式系统的数据一致性问题(三)

    在我的博文里面 关于分布式系统的数据一致性问题(二) 里面主要介绍了数据分布的情况下保证一致性的情况,在第二篇文章里面,我这里提出了三个问题 订单系统调用支付系统支付订单,支付成功,但是返回给订单系统 ...

  3. 不懂这些高并发分布式架构、分布式系统的数据一致性解决方案,你如何能找到高新互联网工作呢?强势解析eBay BASE模式、去哪儿及蘑菇街分布式架构...

    互联网行业是大势所趋,从招聘工资水平即可看出,那么如何提升自我技能,满足互联网行业技能要求?需要以目标为导向,进行技能提升,本文主要针对高并发分布式系统设计.架构(数据一致性)做了分析,祝各位早日走上 ...

  4. 使用云技术升级改造现有应用系统的思考

    办公系统已经上线运行4年了,用户提出升级平台.公文(OA)应用与其它应用相互不影响的需求计划. 其中,升级平台,就是在不额外采购Lisence的情况,平台产品就升级到云计算下的轻量级PaaS平台:公文 ...

  5. 分布式系统数据一致性解决方案

    2019独角兽企业重金招聘Python工程师标准>>> 1.微服务架构的数据一致性问题 以电商平台为例,当用户下单并支付后,系统需要修改订单的状态并且增加用户积分.由于系统采用的是微 ...

  6. 分布式系统(微服务架构)的一致性和幂等性问题相关概念解析

    前言 什么是分布式系统?关于这点其实并没有明确且统一的定义.在我看来,只要一个系统满足以下几点就可以称之为分布式系统 系统由物理上不同分布的多个机器节点组成 系统的多个节点通过网络进行通信,协调彼此之 ...

  7. 分布式系统(微服务架构)的一致性和幂等性和相关概念解析

    1. 分布式系统的数据一致性 1.1 分布式存储系统中的一致性问题 1.2 微服务应用的分布式一致性问题 1.3 对于一致性的正确理解 2.分布式一致性模型 3. 追求强一致性的约束--CAP定理 3 ...

  8. 什么是分布式系统,如何学习分布式系统(转)

    转载自:https://www.cnblogs.com/xybaby/p/7787034.html#_label_5 正文 虽然本人在前面也写过好几篇分布式系统相关的文章,主要包括CAP理论.分布式存 ...

  9. Re:从 0 开始的微服务架构--(四)如何保障微服务架构下的数据一致性--转

    原文地址:http://mp.weixin.qq.com/s/eXvoJew3bjFKzLLJpS0Otg 随着微服务架构的推广,越来越多的公司采用微服务架构来构建自己的业务平台.就像前边的文章说的, ...

最新文章

  1. sybase asa转mysql_为Sybase ASA创建外部存储过程(Java示例)
  2. JTree用法及JTree使用经验总结转
  3. bat小游戏代码大全_Python打砖块小游戏源代码
  4. kafka常见的问题(具体详细)
  5. 几道web前端练习题目
  6. 我来重新学习 javascript 的面向对象(part 1)
  7. c如何调用java_JNI学习------C语言调用Java (转)
  8. 说实话,写了这么多程序了,还从来没有用JUnit作为单元测试工具测试过,今天就来学习一下
  9. Linux Kernel 2.4 Internals
  10. AS3 XML全部用法
  11. 电路设计与仿真各种类软件工具介绍
  12. 计算机管理里面删打印机就卡住了,打印机任务无法删除怎么办-解决打印机任务无法删除的方法 - 河东软件园...
  13. 使用 sed 替换字符串中最后一次出现的字符
  14. java毕业生设计原创网络文学管理系统计算机源码+系统+mysql+调试部署+lw
  15. 除adsense外适合英文站的国外广告联盟(4/12/2011更新)
  16. 怎样利用python写游戏辅助_怎样才能写游戏辅助?
  17. 在高分辨率屏幕上用VMware运行ubuntu显示过小的问题
  18. 内网穿透工具---frp使用教程
  19. SOLID 设计原则 (有点长但很透彻)
  20. latex数学符号加粗_LaTeX技巧458:关于LaTeX数学字体加粗

热门文章

  1. Cachefiled
  2. 使用SQLServer2005插入一条数据时返回当前插入数据的ID
  3. 初识Ildasm.exe——IL反编译的实用工具(转自Youngman)
  4. 【啊哈!算法】之二、插入排序
  5. JS动态添加span等标签
  6. dynamic flash xml news----滚动新闻
  7. Mac OS使用技巧十八:Safari碉堡功能之一制作Widget
  8. windows7黑屏修复_如何在Windows 10更新后修复黑屏
  9. pc微信不支持flash_在出售PC之前,如何取消对Flash内容的授权
  10. java 输入流关闭顺序_Java IO流中先关闭输出流还是先关闭输入流?为什么?