您当前位置:资讯中心 >服务器 >浏览文章

订单系统中的数据一致性方案及RocketMQ事务消息详解

来源:互联网 日期:2023/11/7 7:32:46 阅读量:(0)

数据一致性是确保业务操作正确执行的基础,本文将以电商系统为例,详细分析其分布式系统中的一致性问题。订单核心流程:

订单服务 -> 创建订单 -> 库存服务 -> 扣减库存 -> 积分服务 -> 增加积分 -> 仓储服务 -> 通知发货

分布式一致性技术方案

生产中存在两种常用的解决方案:TCC和可靠消息最终一致性。前者要求强一致,后者要求最终一致。

强一致主要用于核心模块,例如交易/订单等。最终一致一般用于边缘模块例如库存,通过mq去通知,保证最终一致性,也可以业务解耦。

TCC:

订单服务、库存服务、积分服务 -> 绑定为一个TCC事务;

撤销订单时,回滚扣减库存和增加积分。

可靠消息最终一致性:

可以去发送一个请求给消息中间件,由中间件保证一定会把消息交给下游的库存服务去扣减库存,仓储服务去通知发货等;

如果这个过程中有消息发送失败,则可靠消息中间件应该保证不停的重试投递消息。

本文重点分析如何利用RocketMQ的事务消息实现最终一致性,TCC事务将在另外一篇文章分享。

事务消息

RocketMQ的事务消息有两个核心概念(流程):

  • Half Message,半消息

暂时不能被 Consumer消费的消息。Producer已经把消息发送到 Broker端,但是此消息的状态被标记为不能投递,处于这种状态下的消息称为半消息。事实上,该状态下的消息会被放在一个叫做 RMQ_SYS_TRANS_HALF_TOPIC的主题下。

当 Producer端对它二次确认后,也就是 Commit之后,Consumer端才可以消费到;那么如果是Rollback,该消息则会被删除,永远不会被消费到。

  • 事务状态回查

可能会因为网络原因、应用问题等,导致Producer端一直没有对这个半消息进行确认,那么这时候 Broker服务器会定时扫描这些半消息,主动找Producer端查询该消息的状态。

简而言之,RocketMQ事务消息的实现原理就是基于两阶段提交和事务状态回查,来决定消息最终是提交还是回滚的。

核心流程

结合整个订单接口服务,分为两个支付链路,一个是核心链路(订单业务),一个是非核心链路(wms) 整个流程。

先向RocketMQ发送half msg,然后调用核心链路。核心链路要是返回失败,就会走失败的逻辑:退款,更改订单状态为取消,再给rocketmq发送callback废弃掉刚才的消息。

如果成功,就commit msg让消费者可以消费。如果在等待期间,一直没有callback/commit那么mq就会走回调查询具体的状态。

消费者接收到消息后,消费完成就回复mq一个ack, 如果消费失败了,mq就会重新投递或者换一个服务投递。使用rocketmq的half msg机制,可以实现这一套固定模式的最终一致性。

代码实现

【核心链路-订单、库存、积分】

核心业务流程

【步骤一】:发送事务消息(half msg

springboot下,RocketMQ的集成还是很简单的,引入
rocketmq-spring-boot-starter依赖、添加相关配置后,即可利用RocketMQTemplate的sendMessageInTransaction方法发送消息:

/**
 * 发送事务消息
 *
 * @param topic   topic
 * @param message 消息对象
 */
public void sendMessageInTransaction(String topic, Object message) {
    String transactionId = UUID.randomUUID().toString();
    TransactionSendResult result = this.rocketMQTemplate.sendMessageInTransaction(topic, MessageBuilder.withPayload(message)
            .setHeader(RocketMQHeaders.TRANSACTION_ID, transactionId)
            .build(), message);
}
关键字:
声明:我公司网站部分信息和资讯来自于网络,若涉及版权相关问题请致电(63937922)或在线提交留言告知,我们会第一时间屏蔽删除。
有价值
0% (0)
无价值
0% (10)

分享转发:

发表评论请先登录后发表评论。愿您的每句评论,都能给大家的生活添色彩,带来共鸣,带来思索,带来快乐。