乐趣区

关于架构设计:架构设计-基于消息中间件图解柔性事务一致性

简介: 分布式事务基于可靠消息最终一致性的实现计划,既然是可靠消息,则要求 MQ 必须反对事务管理,这样能力保障业务前后一致性。

一、最大致力告诉

TCC 分段提交实用分布式架构中对一致性、实时性要求较高的业务场景,在理论业务中也存在实时性比拟低的业务,例如常见的短信告诉,客户端音讯,经营体系更新等业务,这时候为了加重外围流程的复杂度和压力,能够采取最大致力告诉形式实现柔性事务的治理。

例如常见的第三方领取业务中,本地业务和领取端业务解决实现之后都会生成音讯告诉,根本流程如下:

  • 本地业务预处理实现之后;
  • 申请第三方领取服务;
  • 领取操作胜利对该账号发送音讯;
  • 领取服务回调本地业务;
  • 本地业务生成零碎告诉音讯;

上述流程的音讯场景中有一些根底特点,在外围业务解决实现之后,发送音讯告诉,容许失败,在指定时间段内或者指定重试次数之后,容许音讯失落状况存在,即音讯的不可靠性。

在理论的领取零碎中,启动每日对账校验时会对当日的流水做校验,如果发现领取流水有未实现的流程,会有状态补救,后续能够持续解决,这种伎俩在对账中很罕用。

二、可靠消息

分布式事务基于可靠消息最终一致性的实现计划,既然是可靠消息,则要求 MQ 必须反对事务管理,这样能力保障业务前后一致性。

1、RocketMQ 事务音讯

RocketMQ 在 4.3 版中开始反对分布式事务音讯,采纳 2PC 的思维来实现了提交事务音讯,同时减少一个弥补逻辑来解决二阶段超时或者失败的音讯,如下图所示:

上图阐明了事务音讯的大抵计划,其中分为两个流程:失常事务音讯的发送及提交、事务音讯的弥补流程。

1.1 发送及提交

(1) 发送音讯 (half 音讯,即发送但不被生产);

(2) 服务端响应音讯写入后果;

(3) 依据发送后果执行本地事务, 如果写入失败,此时 half 音讯对业务不可见,本地逻辑不执行;

(4) 依据本地事务状态执行 Commit 或者 Rollback(Commit 操作生成音讯索引,音讯对消费者可见)

1.1 弥补流程

(1) 对没有 Commit/Rollback 的事务音讯(pending 状态的音讯),从服务端发动一次“回查”;

(2)Producer 收到回查音讯,查看回查音讯对应的本地事务的状态;

(3) 依据本地事务状态,从新 Commit 或者 Rollback;

其中,弥补阶段用于解决音讯 Commit 或者 Rollback 产生超时或者失败的状况。

1.3 设计原理

在 RocketMQ 事务音讯的次要流程中,一阶段的音讯如何对用户不可见。其中,事务音讯绝对一般音讯最大的特点就是一阶段发送的音讯对用户是不可见的。那么,如何做到写入音讯然而对用户不可见呢?RocketMQ 事务音讯的做法是:如果音讯是 half 音讯,将备份原音讯的主题与音讯生产队列,而后扭转主题为 RMQ_SYS_TRANS_HALF_TOPIC。因为生产组未订阅该主题,故生产端无奈生产 half 类型的音讯,而后 RocketMQ 会开启一个定时工作,从 Topic 为 RMQ_SYS_TRANS_HALF_TOPIC 中拉取音讯进行生产,依据生产者组获取一个服务提供者发送回查事务状态申请,依据事务状态来决定是提交或回滚音讯。

2、最终一致性

基于上述 RocketMQ 事务音讯可靠性的特点,即能够实现某类业务下事务的最终一致性。音讯发送一致性是指产生音讯的业务动作与音讯发送统一,也就是说如果业务操作胜利,那么由这个业务操作所产生的异步音讯肯定要发送进来,否则就业务失败回滚,音讯也会抛弃。

流程根本如下:

  • 发送 half 事务音讯,无奈被生产;
  • 本地业务代码逻辑解决实现;
  • 发送确认音讯,标识该音讯能够生产;
  • 如果音讯生产方异样,勾销整体动作;

该流程次要针对音讯生产方,在理论开发中,音讯的生产方也一样很难解决,要保障最终一致性,必然会面对一个问题,生产方异样,音讯一直的重试,可能存在局部业务解决胜利,局部业务解决失败的状况,这时候就要解决服务接口的幂等性问题。

三、幂等接口

1、幂等简介

编程中一个幂等操作的特点是其任意屡次执行所产生的影响均与一次执行的影响雷同。就是说,一次和屡次申请某一个资源会产生同样的作用影响。

在简单的异步流程中,尤其留神失败重试问题,通常领取流程中,每次接口被申请,对每一步数据更新的操作,都会前置一步状态查问的流程,用来判断下一步的数据更新是否该执行。

2、幂等接口

在零碎服务接口申请中,任何明确的接口响应,例如失败或胜利,这样业务流程都好解决,然而例如领取场景如果申请超时,如何判断服务的后果状态:客户端申请超时,本地服务超时,申请领取超时,领取回调超时,客户端响应超时等,或者基于 MQ 的一直重试机制,在局部业务异样状态下,始终没有返回胜利,则音讯会始终重试。

这就须要设计流程化的状态治理,尤其在音讯重试机制下,很少会再次对重试的业务接口应用重度的事务管制,有些业务被执行结束,只须要判断一个状态,下次音讯重试跳过即可,只须要把未解决的业务弥补解决即可,在重试机制下,在局部业务没有全副执行胜利之前,音讯会始终重试,直到最终全副实现。

四、源代码地址

GitHub·地址
https://github.com/cicadasmile/data-manage-parent
GitEE·地址
https://gitee.com/cicadasmile/data-manage-parent
退出移动版