如何用 RabbitMQ 解决分布式事务?

要说哪种分布式事务处理方案效率高,必然绕不开消息中间件!基于消息中间件的两阶段提交方案,通常用在高并发场景下。这种方式通过牺牲数据的强一致性换取性能的大幅提升,不过实现这种方式的成本和复杂度是比较高的,使用时还要看实际业务情况。

1. 思路分析

先来说说整体思路。

有一个名词叫做消息驱动的微服务,相信很多小伙伴都听说过。怎么理解呢?

在微服务系统中,服务之间的互相调用,我们可以使用 HTTP 的方式,例如 OpenFeign,也可以使用 RPC 的方式,例如 Dubbo,除了这些方案之外,我们也可以使用消息驱动,这是一种典型的响应式系统设计方案。

在消息驱动的微服务中,服务之间不再互相直接调用,当服务之间需要通信时,就把通信内容发送到消息中间件上,另一个服务则通过监听消息中间件中的消息队列,来完成相应的业务逻辑调用,过程就是这么个过程,并不难,具体怎么玩,我们继续往下看。

2. 业务分析

折腾了半天,后来松哥在网上找到了一个别人写好的例子,我觉得用来演示这个问题特别合适,所以我就没有自己写案例了,直接用别人的代码,我们来逐个分析,跟前面讲分布式事务 Seata 的方式一致。

首先我们来看如下一张流程图,这是一个用户购票的案例:

当用户想要购买一张票时:

  • 向新订单队列中写入一条数据。
  • Order Service 负责消费这个队列中的消息,完成订单的创建,然后再向新订单缴费队列中写入一条消息。
  • User Service 负责消费新订单缴费队列中的消息,在 User Service 中完成对用户账户余额的划扣,然后向新订单转移票队列中写入一条消息。
  • Ticket Service 负责消费新订单转移票队列,在 Ticket Service 中完成票的转移,然后发送一条消息给订单完成队列。
  • 最后 Order Service 中负责监听订单完成队列,处理完成后的订单。

这就是一个典型的消息驱动微服务,也是一个典型的响应式系统。在这个系统中,一共有三个服务,分别是:

  • Order Service
  • User Service
  • Ticket Service

这三个服务之间不会进行任何形式的直接调用,大家有事都是直接发送到消息中间件,其他服务则从消息中间件中获取自己想要的消息然后进行处理。

具体到我们的实践中,则多了一个检查票是否够用的流程,如下图:

创建订单时,先由 Ticket 服务检查票是否够用,没问题的话再继续发起订单的创建。其他过程我就不说了。

另外还需要注意,在售票系统中,由于每张票都不同,例如每张票可能有座位啥的,因此一张票在数据库中往往是被设计成一条记录。

3. 实践

流程我已经说明白了,接下来我们就来看看具体的代码实践。

3.1 准备数据库

首先我们准备三个数据库,分别是:

javaboy_order:订单库,用户创建订单等操作,在这个数据库中完成。

javaboy_ticket:票务库,这个库中保存着所有的票据信息,每一张票都是一条记录,都保存在这个库中。

javaboy_user:用户库,这里保存着用户的账户余额以及付款记录等信息。

每个库中都有各自对应的表,为了操作方便,这些表不用自己创建,将来等项目启动了,利用 JPA 自动创建即可。

3.2 项目概览

我们先来整体上看下这个项目,公众号后台回复 mq_tran 可以下载完整代码:

一共有五个服务:

  • eureka:注册中心
  • order:订单服务
  • service:公共模块
  • ticket:票务服务
  • user:用户服务
  • 下面分别来说。

3.3 注册中心

有人说,都消息驱动了,还要注册中心干嘛?

消息驱动没错,消息驱动微服务之后每个服务只管把消息往消息中间件上扔,每个服务又只管消费消息中间件上的消息,这个时候对于服务注册中心似乎不是那么强需要。不过在我们这个案例中,消息驱动主要用来处理事务问题,其他常规需求我们还是用 OpenFeign 来处理,所以这里我们依然需要一个注册中心。

这里的注册中心我就选择常见的 Eureka,省事一些。由于本文主要是和大家聊分布式事务,所以涉及到微服务的东西我就简单介绍下,不会占用过多篇幅,如果大家还不熟悉 Spring Cloud 的用法,可以在公众号后台回

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值