RocketMQ的事务消息和改造

什么是 rmq分布式事务消息

Apache RocketMQ在4.3.0版中已经支持分布式事务消息,这里RocketMQ采用了2PC的思想来实现了提交事务消息,同时增加一个补偿逻辑来处理二阶段超时或者失败的消息,如下图所示。

事务消息解决什么问题?

本地事务与消息发送的原子性问题。

简单解释:本地事务提交,消息肯定发出去;本地事务回滚,消息肯定不能发出去。

目前事务消息现状

chd 基于 rmq 提供的事务消息方案,通过本地事务记录表,简化事务消息开发,封装了上图第6步,提供通用回查的逻辑。

以下单流程为例,简述目前 chd 开发者使用事务消息流程:

以下代码示例当前事务消息开发使用过程:

基于现状,目前使用 rmq 官方提供二阶段事务消息存在以下痛点。

痛点一: 开发理解、使用成本高。

如果不理解 rmq 2pc 事务消息,业务中很难用对、用好。例如忘记很重要的一步 判断事务执行结果

痛点二:rmq事务消息使用时,事务开始前就得构造好业务消息体,但很多情况下只有事务内执行时才能获取到消息体内容

这种场景根本没法使用,或业务代码改造成本很高,例如改造为两个事件并使用中间数据关联。

痛点三:本地事务内发送 rmq 非事务消息,出现本地事务还没提交消息都发出去被错误消费,导致误以为丢消息

如果日志不完善,排查业务问题难度大。这种情况会出现要么被错误消费(事务没提交,查到数据是老的),要么误认为丢消息(消费时回查没数据直接忽略)

其他痛点待整理

因此,分析以上问题,需要提供业务代码侵入低、使用成本低,并能解决以上痛点的本地事务消息表方案

本地事务消息表最终一致性方案

改造思路:

1. 本地存储事务消息内容,和业务流程事务一起成功一起失败
2. 监听事务管理器提交事务的动作,事务提交后再去执行实时发消息
3. 假设事物提交后实时发送消息失败,要有补偿机制确保消息最终能发出去

以下单流程为例,简述实现过程:

开发者使用方式示例

其他内容待整理

SQL备注

ALTER TABLE `xi_local_transaction_log` ADD COLUMN `sendStatus` tinyint UNSIGNED NOT NULL DEFAULT '0' COMMENT '发送状态', ADD COLUMN `payload` text COMMENT '消息载体,json';
ALTER TABLE `order_local_transaction_log` ADD COLUMN `sendStatus` tinyint UNSIGNED NOT NULL DEFAULT '0' COMMENT '发送状态', ADD COLUMN `payload` text COMMENT '消息载体,json';
ALTER TABLE `vaccine_local_transaction_log` ADD COLUMN `sendStatus` tinyint UNSIGNED NOT NULL DEFAULT '0' COMMENT '发送状态', ADD COLUMN `payload` text COMMENT '消息载体,json';

ALTER TABLE `activity_local_transaction_log` ADD COLUMN `sendStatus` tinyint UNSIGNED NOT NULL DEFAULT '0' COMMENT '发送状态', ADD COLUMN `payload` text COMMENT '消息载体,json';
ALTER TABLE `user_local_transaction_log` ADD COLUMN `sendStatus` tinyint UNSIGNED NOT NULL DEFAULT '0' COMMENT '发送状态', ADD COLUMN `payload` text COMMENT '消息载体,json';
ALTER TABLE `commodity_local_transaction_log` ADD COLUMN `sendStatus` tinyint UNSIGNED NOT NULL DEFAULT '0' COMMENT '发送状态', ADD COLUMN `payload` text COMMENT '消息载体,json';
ALTER TABLE `knowledge_local_transaction_log` ADD COLUMN `sendStatus` tinyint UNSIGNED NOT NULL DEFAULT '0' COMMENT '发送状态', ADD COLUMN `payload` text COMMENT '消息载体,json';
ALTER TABLE `credit_local_transaction_log` ADD COLUMN `sendStatus` tinyint UNSIGNED NOT NULL DEFAULT '0' COMMENT '发送状态', ADD COLUMN `payload` text COMMENT '消息载体,json';
ALTER TABLE `distribution_local_transaction_log` ADD COLUMN `sendStatus` tinyint UNSIGNED NOT NULL DEFAULT '0' COMMENT '发送状态', ADD COLUMN `payload` text COMMENT '消息载体,json';

CREATE TABLE `commodity_local_transaction_log` (
  `id` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '全局id',
  `createTime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `modifyTime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
  `transactionId` varchar(32) NOT NULL DEFAULT '' COMMENT '事务ID',
  `topic` varchar(64) NOT NULL DEFAULT '' COMMENT 'topic名称',
  `tag` varchar(64) NOT NULL DEFAULT '' COMMENT 'tag名称',
  `sendStatus` tinyint UNSIGNED NOT NULL DEFAULT '0' COMMENT '发送状态',
  `payload` text COMMENT '消息载体,json',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uniq_transactionId` (`transactionId`)
) DEFAULT CHARSET=utf8mb4 COMMENT='MQ事务消息记录表';

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值