RocketMQ事务消息

首先要明白,事务消息是基于两阶段提交来完成的

概述

  • 第一阶段:也就是发送 Message,但这里的 Message 叫 Half Message,即半事务消息。此类型的 Message 是不会被 Consumer 消费到的。

  • 第二阶段:如果半事务消息投递成功,则会开始执行本地事务。这里分为如下三种情况。

    • 如果本地事务执行成功,则会向 Broker 发送 commit 消息,被 commit 过后的 Message 才能被 Consumer 消费到。

    • 如果本地事务执行失败,则会向 Broker 发送 rollback 消息,Broker 则会将刚刚投递的半事务消息删除,从而保证上下游数据的一致性。

    • 如果 Producer 实例或者网络出现了问题,Producer 没能及时地将本地事务执行的结果通知 Broker,Broker 会通过扫描发现某条 Message 长时间处于“半事务消息”状态,Broker 会变被动为主动,主动地向 Producer 询问此 Message 对应的事务状态。

这就是事务消息的大致原理。

 详情

Producer操作部分

1 检查TransactionListener等组件是否被初始化

2 清除消息的延迟属性(事务不支持延迟)

3 将消息标记为Half Message(半事务消息

Producer 会向 Message 的 Property 当中写入属性

4 将事务消息投递到Broker

Broker部分

1 检查是否为事务消息,与普通消息分流

2 储存事务消息,并备份原Topic与Messagequeue

类似延迟消息,事务消息专门储存在RMQ_SYS_TRANS_HALF_TOPIC的Topic中,不过它只有一个队列,都储存在0号队列中。(一个 Topic 下如果只有 1 个 MessageQueue,那么这个 Topic 下的所有 Message 就是全局有序的,它们会按照先来后到的顺序被消费)

3 Producer执行本地事务,将结果发给Broker,Producer 会向 Broker 发送一个 RequestCode 为 END_TRANSACTION 的请求,来通知 Broker 执行相关操作。

4 Broker根据事务执行结果判断

  • commit,根据offset(偏移量,用来定位消息)取出Half Message,

        构建新的Message,还原其Topic与 Messagequeue,重新投递,并再次持久化储存。

        还会将原先的Half Message打上删除tags(标签)

  • Rollback,删除Half Message
  • UnKnow,进行事务回查
  • 删除的都会扔入RMQ_SYS_TRANS_OP_HALF_TOPIC队列

5 事务回查

Broker在启动时创建线程一分钟扫描一次事务消息队列中是否需要回查,有两个关键参数:

  • timeout,超过这个时间后才会进行回查,6秒
  • checkMax,最大回查几次,超过就删除

6 回查过程

  • 取出Half Message
  • 进行各种校验,是否被删,是否达到最大次数,是否达到最大存活时间,默认3天

以上任何校验不通过就会被丢弃,

扔入TRANS_CHECK_MAX_TIME_TOPIC队列

  • 将当前 Message 再次投递进事务消息专用队列当中,为什么呢?

这是因为,一旦判定为需要执行事务回查逻辑,那么当前这条 Half Message 就算已经被消费了。但如果后续调用 resolveHalfMsg() 失败了没有拿到结果怎么办?这里明显是还要重试的,所以为了让整个链路串起来,在没达到最大的校验次数之前,都还需要将其投递到事务队列当中,以便下次再次执行 Check 逻辑。

  • Broker异步向Produce查询事务状态

Broker 会向 Producer 发送一个 RequestCode 为 CHECK_TRANSACTION_STATE 的请求

  • Producer 拿到事务的结果之后,会向 Broker 发送 RequestCode 为 END_TRANSACTION 的请求,串起来了

附带一张很不错的流程图

正常消费:

异常消费:(事务失败)

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值