前提

  • 所有服务均有独立的事物管理机制,相互间没有任何关联.
  • 所有业务接口都有对应的补偿方法,用于将已经更新的数据还原到上一次的状态.
  • 本次实例为同步业务,理想状态下,只有全部成功或全部失败两种情况.

正式开始

正常流程

一切安好.

中途异常 - 补偿成功

虽然发生了失败,但所有补偿都成功了.没有什么问题

中途异常 - 补偿失败

此时,主服务有三种处理方法

  1. 主服务无限重试补偿方法,直到补偿成功.
    这里有很麻烦的问题,如果下游的服务器已经停机,此时主服务的无限重试已经没有意义.在最坏的情况下,如果主服务访问量过大,而因为业务相同,主服务的线程池中的全部线程将全部处于阻塞状态,失去处理新请求的能力.
    同时,访问主服务的客户端有可能会放弃本次的连接,导致正在重试中的线程被回收,丢失所有状态
  2. 主服务尽可能调用补偿方法,并回滚自身事物,同时通知备用方案
    这里依靠备用方案对失败的补偿调用进行异步异步调用,已达到"最终一致"的效果.备用方案一般需要集成"可靠消息系统"
  3. 主服务直接放弃补偿与自身的回滚,并通知备用方案
    与2基本相同.在调用链比较长的情况下且补偿随机性失败,从上层看,2方案的调用结果(备用方案未执行时)将成锯齿状.而本方案,其对应
    的消费者直接以级联方式进行补偿的调用,最终完成全部补偿调用与主方法数据回滚,同样从上层看,方案3的调用结果(备用方案未执行时)将是平整的(只有失败处断裂).

方案1直接pass
方案2,3可以使用消息队列与对应的消费者进行实现.但是会有短暂的数据不一致问题

中途异常(伪) - 触发补偿

这种情况具体描述如下

  1. 正常远程调用
  2. 下游业务接收并进行处理
  3. 主服务认为网络超时(如等待数据库锁释放)或发生其他意外,从而触发补偿流程
  4. 下游业务完成请求处理
  5. 主服务发起并执行补偿流程(不包含4涉及的服务)

解决方法

  1. 记录全局唯一识别码,当主服务发起补偿时,所有下游业务应该得知,并出发各自的补偿方法.
  2. 需要注意,在尝试解决过程中,如果主服务过早推送回滚通知,涉及独自提交的服务早于对应业务处理完成进行补偿,将会导致回滚通知失效.

    在这种情况下,上游业务回滚,下游业务独自完成了业务处理,造成数据问题. 会有短暂的数据不一致问题
    同样的,在这种情况下,调用补偿也有可能发生调用失败的情况.并且会更复杂,因为此时主服务会发出全局的回滚消息,需要处理补偿消息与回滚消息的顺序问题

主服务断电 - 正常运行,补偿中,补偿失败中


此时主服务状态全部丢失且下游业务状态错乱

只能借用可靠消息对进行中的操作进行记录,并在再次开启后进行恢复

总结

  • 在必须要使用RPC进行远程调用且事物复杂的情况下,应使用一个可靠的消息系统保证在各方断电,断网,回滚时能够即使恢复"状态".
  • 同时,应保证严格的幂等性,对于非幂等消息,根据实际情况,进行保留会消耗.
  • 所有经由消息系统的恢复性调用,均为异步操作,此时各方数据会出现不同步的问题.
  • 对于复杂性,即使是只有2步,也会产生意外,且补偿方法并不可靠.必须使用"可靠消息"系统进行保证(就是说,不要想要有"方便"这两个字).
  • 对于调用消息,进行两步验证,要做xxx与完成xxx,同时保证复苏用的业务数据即可.对于全局回滚消息,进行通用,同时保证复苏消息与回滚消息的幂等
  • 主服务自身的业务逻辑也应做成远程调用的模式,即有常规与补偿方法.而主方法本身不包含事物,以此进行统一管理
  • 基于上述的内容,已经很靠近TCC模式了,且需要扩展很多框架级代码与补偿代码.

分布式事物 - 基于RPC调用 - 补偿模式的更多相关文章

  1. 分布式事物 - 基于RPC调用 - TCC模式

    前提 前端业务(主服务)可以以同步或异步调用TCC框架,或者TCC框架本身就是同步异步兼备的. 假定TCC框架拥有断电后的自动恢复能力.同时,在下游业务出现无限失败的情况下,也会进行无限的重试,以达到 ...

  2. Solon rpc 之 SocketD 协议 - RPC调用模式

    Solon rpc 之 SocketD 协议系列 Solon rpc 之 SocketD 协议 - 概述 Solon rpc 之 SocketD 协议 - 消息上报模式 Solon rpc 之 Soc ...

  3. C#中的异步调用及异步设计模式(三)——基于事件的异步模式

    四.基于事件的异步模式(设计层面) 基于事件的C#异步编程模式是比IAsyncResult模式更高级的一种异步编程模式,也被用在更多的场合.该异步模式具有以下优点: ·                 ...

  4. 《精通并发与Netty》学习笔记(07 - 基于Thrift实现Java与Python的RPC调用)

    上节我们介绍了基于Thrift实现java与java的RPC调用,本节我们基于Thrift实现Java与Python的RPC调用 首先,修改data.thirft文件,将命名空间由java改为py n ...

  5. storm drpc分布式本地和远程调用模式讲解

    一.drpc 的介绍 1.rpc RPC(Remote Procedure Call)—远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议. 2.drpc drp ...

  6. 在这个应用中,我使用了 MQ 来处理异步流程、Redis 缓存热点数据、MySQL 持久化数据,还有就是在系统中调用另外一个业务系统的接口,对我的应用来说这些都是属于 RPC 调用,而 MQ、MySQL 持久化的数据也会存在于一个分布式文件系统中,他们之间的调用也是需要用 RPC 来完成数据交互的。

    在这个应用中,我使用了 MQ 来处理异步流程.Redis 缓存热点数据.MySQL 持久化数据,还有就是在系统中调用另外一个业务系统的接口,对我的应用来说这些都是属于 RPC 调用,而 MQ.MySQ ...

  7. Atomikos和GTS-Fescar和TCC-Transaction和TX-LCN分布式事物的比较

    什么是分布式事物 分布式系统中保证不同节点之间的数据一致性的事物,叫做分布式事物. 为什么要用分布式事物 微服务,SOA等服务架构模式,一个是service产生多个节点,另一个是resource产生多 ...

  8. Zookeeper——基本使用以及应用场景(手写实现分布式锁和rpc框架)

    文章目录 Zookeeper的基本使用 Zookeeper单机部署 Zookeeper集群搭建 JavaAPI的使用 Zookeeper的应用场景 分布式锁的实现 独享锁 可重入锁 实现RPC框架 基 ...

  9. 闲话RPC调用

    原创文章转载请注明出处:@协思, http://zeeman.cnblogs.com 自SOA架构理念提出以来,应用程序间如何以最低耦合度通信的问题便呈现在所有架构师面前. 互联网系统的复杂度让我们不 ...

随机推荐

  1. nginx常用模块(三)

    Nginx常用模块(三) ngx_http_proxy_module模块配置(http或https协议代理) proxy_pass URL; 应用上下文:location, if in locatio ...

  2. SpringBoot源码学习系列之异常处理自动配置

    SpringBoot源码学习系列之异常处理自动配置 1.源码学习 先给个SpringBoot中的异常例子,假如访问一个错误链接,让其返回404页面 在浏览器访问: 而在其它的客户端软件,比如postm ...

  3. TensorBoard:可视化学习

    数据序列化 TensorBoard 通过读取 TensorFlow 的事件文件来运行.TensorFlow 的事件文件包括了你会在 TensorFlow 运行中涉及到的主要数据.下面是 TensorB ...

  4. 数据表与简单java类——多对多映射

    给定一张Meber和Product表,得到如下信息: 1.获取一个用户访问的所有商品信息 2.获取一个商品被哪些用户浏览过的信息 package Mapping_transformation; cla ...

  5. 虚拟机配置net模式

    在cmd中输入ipconfig -all查看 更改网络适配器 进入虚拟机左上角编辑----虚拟机网络编辑器查看VMnet8,虚拟机会为我们分配的固定ip段:如下图: ip段是128---254,所以设 ...

  6. react新版本配置代理

    新学习react 开始配置react跨域的时候 在网上查看到是在packjson.json里面添加如下代码: "proxy": { "/api": { &quo ...

  7. Netty学习——Netty和Protobuf的整合(二)

    Netty学习——Netty和Protobuf的整合(二) 这程序是有瑕疵的,解码器那里不通用,耦合性太强,有两个很明显的问题,但是要怎么解决呢?如:再加一个内部类型 Person2,之前的代码就不能 ...

  8. iOS 网络基本剖析

    一.网络通信的本质 数据传输,数据交换 Client     <======>  服务器 二.HTTP.TCP,IP.UDP.Socket关系刨析 Socket:套接字,是一个用于网络传输 ...

  9. SDCycleScrollView-简单的循环

    cocoapods 导入SDCycleScrollView1 记得使用 SDWebImage 2 SDCycleScrollViewDelegate _cycleScrollerView = [SDC ...

  10. iOS开发动画(Animation)总结

    UIView的,翻转.旋转,偏移,翻页,缩放,取反的动画效果   翻转的动画 //开始动画 [UIView beginAnimations:@"doflip" context:ni ...