站点图标 起风网

事务消息应用场景、实现原理与项目实战

简介:从应用场景出发,给出解决方案与实现原理,并提供整套工业级实现源码。

作者:丁威

活动中心场景介绍

在电商系统上线初期,往往会进行一些“拉新”活动,例如活动部门提出新用户注册送积分、送优惠券活动。

基于分布式、微服务的设计理念,通常的架构设计(子系统交互)如下图所示:

其核心系统介绍如下:

上面的架构设计非常优雅,但并不是无懈可击,如果新用户注册成功,但消息发送到 MQ 失败,或者消息成功发送到 MQ,但发送完 MQ 后系统出现异常导致用户注册失败又该如何呢?

上面的问题其实就是典型的分布式事务问题:即如何保证用户注册(数据库操作)与 MQ 消息发送这两个分布式操作的一致性。

RocketMQ 事务消息闪亮登场。

事务消息实现原理

一言以蔽之:RocketMQ 事务消息要解决的问题是消息发送与业务的一致性,其解决思路:二阶段提交与事务状态回查,其具体实现流程如下图所示:

其核心设计理念:

在具体实践中,消息发送者在无法获取事务状态时不要武断的返回 ROLLBACK,而是要返回 UNOWN,让服务端定时重试回查,说明如下:

在将 PREPARE 消息发送到 Broker 后,服务端发起事务查询时本地事务可能还未提交,为了避免无效的事务回查机制,RocketMQ 通常至少在收到 PREPARE 消息 6s 后才会发起第一次事务回查,可通过 transactionTimeOut 配置。故客户端在实现事务回查时无法证明事务状态时不应该返回 ROLLBACK,而是返回 UNOWN。

事务消息实战

光说不练假把式,接下来以一个新用户注册送优惠券的场景来详细介绍如何使用事务消息。

项目模块职责说明如下:

事务消息的核心代码组装在 transaction-service,其核心类图如下:

其中核心要点如下:

温馨提示:之所以不在 UserServicveImpl 中执行本地事务,是因为 executeLocalTransaction 中抛出的异常会被 RocketMQ 框架捕捉,及异常无法被 UserServiceImpl 感知,即无法实现其事务的一致性。

接下来展示其核心代码,全部源码已上传到 github 仓库。

仓库地址:https://github.com/dingwpmz/rocketmq-learning

UserServiceImpl 核心实现

UserServiceImpl 的核心要点如下


UserRegTransactionListener 核心实现

事务监听器需要实现执行本地事务与事务回查两个接口。

1、实现 executeLocalTransaction

首先需要实现 executeLocalTransaction 方法,执行本地事务,其代码如下图所示:

其中几个关键点说明如下:

2、实现 checkLocalTransaction

其次需要实现事务状态回查,用来 RocketMQ 服务端感知事务是否成功,其实现原理如下图所示:

其实现关键点如下:


代码获取

上文只是将事务消息的核心代码加以解读,并重点阐述每个步骤的实现关键点,笔者基于 SpringBoot,尝试结合场景学习 RocketMQ 的使用技巧,其代码上传到了 github 仓库:https://github.com/dingwpmz/rocketmq-learning

点击跳转到代码仓库

原文链接:https://developer.aliyun.com/article/783534?

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

原文链接:https://blog.csdn.net/alitech2017/article/details/115961314

本站声明:网站内容来源于网络,如有侵权,请联系我们,我们将及时处理。

退出移动版