作者:合伯

导言:在分布式体系调用场景中存在这样一个通用问题,即在履行一个中心事务逻辑的一起,还需求调用多个下流做事务处理,而且要求多个下流事务和当时中心事务有必要一起成功或许一起失败,进而防止部分成功和失败的不共同状况呈现。简略来说,音讯行列中的“事务”,首要处理的是音讯生产者和顾客的数据共同性问题。本篇文章经过拆解 RocketMQ 事务音讯的运用场景、根本原理、完结细节和实战运用,帮助我们更好的了解和运用 RocketMQ 的事务音讯。

点击下方链接,查看视频解说:

yqh.aliyun.com/live/detail…

场景:为什么需求事务音讯

以电商买卖场景为例,用户支付订单这一中心操作的一起会涉及到下流物流发货、积分改变、购物车状况清空等多个子体系的改变。当时事务的处理分支包含:

  • 主分支订单体系状况更新:由未支付改变为支付成功;
  • 物流体系状况新增:新增待发货物流记载,创建订单物流记载;
  • 积分体系状况改变:改变用户积分,更新用户积分表;
  • 购物车体系状况改变:清空购物车,更新用户购物车记载。

解析 RocketMQ 业务消息——“事务消息”

分布式体系调用的特点是:一个中心事务逻辑的履行,一起需求调用多个下流事务进行处理。因而,怎么确保中心事务和多个下流事务的履行成果完全共同,是分布式事务需求处理的首要问题。

传统 XA 事务计划:功用缺乏

为了确保上述四个分支的履行成果共同性,典型计划是依据XA协议的分布式事务体系来完结。将四个调用分支封装成包含四个独立事务分支的大事务,依据XA分布式事务的计划可以满足事务处理成果的正确性,但最大的缺陷是多分支环境下资源承认范围大,并发度低,随着下流分支的添加,体系功用会越来越差。

依据一般音讯计划:共同性确保困难

将上述依据 XA 事务的计划进行简化,将订单体系改变作为本地事务,剩下的体系改变作为一般音讯的下流来履行,事务分支简化成一般音讯+订单表事务,充分利用音讯异步化的才能缩短链路,进步并发度。

解析 RocketMQ 业务消息——“事务消息”

该计划中音讯下流分支和订单体系改变的主分支很简单呈现不共同的现象,例如:

  • 音讯发送成功,订单没有履行成功,需求回滚整个事务;
  • 订单履行成功,音讯没有发送成功,需求额定补偿才能发现不共同;
  • 音讯发送超时不知道,此刻无法判别需求回滚订单仍是提交订单改变。

依据RocketMQ分布式事务音讯:支持终究共同性

上述一般音讯计划中,一般音讯和订单事务无法确保共同的实质原因是一般音讯无法像单机数据库事务相同,具备提交、回滚和统一协调的才能。

而依据音讯行列 RocketMQ 版完结的分布式事务音讯功用,在一般音讯基础上,支持二阶段的提交才能。将二阶段提交和本地事务绑定,完结大局提交成果的共同性。

解析 RocketMQ 业务消息——“事务消息”

音讯行列 RocketMQ 版事务音讯的计划,具备高功用、可扩展、事务开发简略的优势。

根本原理

概念介绍

  • 事务音讯:RocketMQ 提供类似 XA 或 Open XA 的分布式事务功用,经过 RocketMQ 事务音讯能达到分布式事务的终究共同;

  • 半事务音讯:暂不能投递的音讯,生产者现已成功地将音讯发送到了 RocketMQ 服务端,可是 RocketMQ 服务端未收到生产者对该音讯的二次承认,此刻该音讯被符号成“暂不能投递”状况,处于该种状况下的音讯即半事务音讯;

  • 音讯回查:因为网络闪断、生产者使用重启等原因,导致某条事务音讯的二次承认丢掉,RocketMQ 服务端经过扫描发现某条音讯长时刻处于“半事务音讯”时,需求主意向音讯生产者问询该音讯的终究状况(Commit 或是 Rollback),该问询进程即音讯回查。

事务音讯生命周期

解析 RocketMQ 业务消息——“事务消息”

  • 初始化:半事务音讯被生产者构建并完结初始化,待发送到服务端的状况;

  • 事务待提交:半事务音讯被发送到服务端,和一般音讯不同,并不会直接被服务端耐久化,而是会被单独存储到事务存储体系中,等候第二阶段本地事务回来履行成果后再提交。此刻音讯对下流顾客不行见;

  • 音讯回滚:第二阶段假如事务履行成果清晰为回滚,服务端会将半事务音讯回滚,该事务音讯流程终止;

  • 提交待消费:第二阶段假如事务履行成果清晰为提交,服务端会将半事务音讯从头存储到一般存储体系中,此刻音讯对下流顾客可见,等候被顾客获取并消费;

  • 消费中:音讯被顾客获取,并依照顾客本地的事务逻辑进行处理的进程。此刻服务端会等候顾客完结消费并提交消费成果,假如必定时刻后没有收到顾客的呼应,RocketMQ 会对音讯进行重试处理。详细信息,请拜见音讯重试;

  • 消费提交:顾客完结消费处理,并向服务端提交消费成果,服务端符号当时音讯现已被处理(包含消费成功和失败);RocketMQ 默许支持保留一切音讯,此刻音讯数据并不会立即被删去,仅仅逻辑符号已消费。音讯在保存时刻到期或存储空间缺乏被删去前,顾客仍然可以回溯音讯从头消费。

  • 音讯删去:当音讯存储时长到期或存储空间缺乏时,RocketMQ 会依照翻滚机制整理最早保存的音讯数据,将音讯从物理文件中删去。

事务音讯根本流程

事务音讯交互流程如下图所示:

解析 RocketMQ 业务消息——“事务消息”

  1. 生产者将音讯发送至 RocketMQ 服务端;

  2. RocketMQ 服务端将音讯耐久化成功之后,向生产者回来 Ack 承认音讯现已发送成功,此刻音讯被符号为“暂不能投递”,这种状况下的音讯即为半事务音讯;

  3. 生产者开始履行本地事务逻辑;

  4. 生产者依据本地事务履行成果向服务端提交二次承认成果(Commit 或是 Rollback),服务端收到承认成果后处理逻辑如下:

    • 二次承认成果为 Commit:服务端将半事务音讯符号为可投递,并投递给顾客;
    • 二次承认成果为 Rollback:服务端将回滚事务,不会将半事务音讯投递给顾客。
  1. 在断网或许是生产者使用重启的特别状况下,若服务端未收到发送者提交的二次承认成果,或服务端收到的二次承认成果为Unknown不知道状况,经过固定时刻后,服务端将对音讯生产者即生产者集群中任一生产者实例建议音讯回查;

  2. 生产者收到音讯回查后,需求查看对应音讯的本地事务履行的终究成果;

  3. 生产者依据查看到的本地事务的终究状况再次提交二次承认,服务端仍依照进程 4 对半事务音讯进行处理。

完结细节:RocketMQ 事务音讯怎么完结

解析 RocketMQ 业务消息——“事务消息”

依据发送事务音讯的根本流程的需求,完结分为三个首要流程:接纳处理 Half 音讯、Commit 或 Rollback 指令处理、事务音讯 check。

处理 Half 音讯

发送方第一阶段发送 Half 音讯到 Broker 后,Broker 处理 Half 音讯。Broker 流程参阅下图:

解析 RocketMQ 业务消息——“事务消息”

详细流程是首要把音讯转换 Topic 为 RMQ_SYS_TRANS_HALF_TOPIC,其余音讯内容不变,写入 Half 行列。详细完结参阅 SendMessageProcessor 的逻辑处理。

Commit 或 Rollback 指令处理

发送方完结本地事务后,持续发送 Commit 或 Rollback 到 Broker。因为当时事务现已完结,Broker 需求删去原有的 Half 音讯,因为 RocketMQ 的 appendOnly 特性,Broker经过 OP 音讯完结符号删去。Broker 流程参阅下图:

解析 RocketMQ 业务消息——“事务消息”

  • Commit。Broker 写入 OP 音讯,OP 音讯的 body 指定 Commit 音讯的 queueOffset,符号之前 Half 音讯已被删去;一起,Broker 读取原 Half 音讯,把 Topic 复原,从头写入 CommitLog,顾客则可以拉取消费;

  • Rollback。Broker 同样写入 OP 音讯,流程和 Commit 相同。但后续不会读取和复原 Half 音讯。这样顾客就不会消费到该音讯。

详细完结在 EndTransactionProcessor 中。

事务音讯 check

假如发送端事务时刻履行进程,发送 UNKNOWN 指令,或许 Broker/发送端重启发布等原因,流程 2 的符号删去的 OP 音讯可能会缺失,因而添加了事务音讯 check 流程,该流程是在异步线程定时履行(transactionCheckInterval 默许 30s 间隔),针对这些缺失 OP 音讯的 Half 音讯进行 check 状况。详细参阅下图:

解析 RocketMQ 业务消息——“事务消息”

事务音讯 check 流程扫描当时的 OP 音讯行列,读取现已被符号删去的 Half 音讯的 queueOffset。假如发现某个 Half 音讯没有 OP 音讯对应符号,而且现已超时(transactionTimeOut 默许 6 秒),则读取该 Half 音讯从头写入 half 行列,而且发送 check 指令到原发送方查看事务状况;假如没有超时,则会等候后读取 OP 音讯行列,获取新的 OP 音讯。

别的,为了防止发送方的反常导致长时刻无法承认事务状况,假如某个 Half 音讯的 bornTime 超过最大保留时刻(transactionCheckMaxTimeInMs 默许 12 小时),则会自动跳过此音讯,不再 check。

详细完结参阅:

TransactionalMessageServiceImpl#check 办法。

实战:运用事务音讯

了解了 RocketMQ 事务音讯的原理后,咱们看下怎么运用事务。首要,咱们需求创建一个 “事务音讯” 类型的 Topic,可以运用控制台或许 CLi 指令创建。

解析 RocketMQ 业务消息——“事务消息”

事务音讯相比一般音讯发送时需求修正以下几点:

  • 发送事务音讯前,需求敞开事务并关联本地的事务履行。
  • 为确保事务共同性,在构建生产者时,有必要设置事务查看器和预绑定事务音讯发送的主题列表,客户端内置的事务查看器会对绑定的事务主题做反常状况恢复。

解析 RocketMQ 业务消息——“事务消息”

当事务音讯 commit 之后,这条音讯其实就是一条投递到用户 Topic 的一般音讯罢了。所以对于顾客来说,和一般音讯的消费没有差异。

解析 RocketMQ 业务消息——“事务消息”

注意:

  1. 防止很多未决事务导致超时:在事务提交阶段反常的状况下建议事务回查,确保事务共同性;但生产者应该尽量防止本地事务回来不知道成果;很多的事务查看会导致体系功用受损,简单导致事务处理推迟;
  2. 事务音讯的 Group ID 不能与其他类型音讯的 Group ID 共用:与其他类型的音讯不同,事务音讯有回查机制,回查时服务端会依据 Group ID 去查询生产者客户端;
  3. 事务超时机制:半事务音讯被生产者发送服务端后,假如在指定时刻内服务端无法承认提交或许回滚状况,则音讯默许会被回滚。

今天经过对RocketMQ事务音讯的介绍,希望能够帮我们对事务音讯的原理和使用有更深入的了解,一起也期望 RocketMQ的事务音讯能够帮助您更有用的处理事务问题。假如您对RocktMQ的事务音讯感兴趣,也欢迎您扫描下方二维码加入钉钉群一起沟通交流~

解析 RocketMQ 业务消息——“事务消息”

点击此处,进入官网了解更多概况~