赞
踩
要说哪种分布式事务处理方案效率高,必然绕不开消息中间件!基于消息中间件的两阶段提交方案,通常用在高并发场景下。这种方式通过牺牲数据的强一致性换取性能的大幅提升,不过实现这种方式的成本和复杂度是比较高的,使用时还要看实际业务情况。
先来说说整体思路。
有一个名词叫做消息驱动的微服务,相信很多小伙伴都听说过。怎么理解呢?
在微服务系统中,服务之间的互相调用,我们可以使用 HTTP 的方式,例如 OpenFeign,也可以使用 RPC 的方式,例如 Dubbo,除了这些方案之外,我们也可以使用消息驱动,这是一种典型的响应式系统设计方案。
在消息驱动的微服务中,服务之间不再互相直接调用,当服务之间需要通信时,就把通信内容发送到消息中间件上,另一个服务则通过监听消息中间件中的消息队列,来完成相应的业务逻辑调用,过程就是这么个过程,并不难,具体怎么玩,我们继续往下看。
折腾了半天,后来松哥在网上找到了一个别人写好的例子,我觉得用来演示这个问题特别合适,所以我就没有自己写案例了,直接用别人的代码,我们来逐个分析,跟前面讲分布式事务 Seata 的方式一致。
首先我们来看如下一张流程图,这是一个用户购票的案例:
当用户想要购买一张票时:
这就是一个典型的消息驱动微服务,也是一个典型的响应式系统。在这个系统中,一共有三个服务,分别是:
这三个服务之间不会进行任何形式的直接调用,大家有事都是直接发送到消息中间件,其他服务则从消息中间件中获取自己想要的消息然后进行处理。
具体到我们的实践中,则多了一个检查票是否够用的流程,如下图:
创建订单时,先由 Ticket 服务检查票是否够用,没问题的话再继续发起订单的创建。其他过程我就不说了。
另外还需要注意,在售票系统中,由于每张票都不同,例如每张票可能有座位啥的,因此一张票在数据库中往往是被设计成一条记录。
流程我已经说明白了,接下来我们就来看看具体的代码实践。
3.1 准备数据库
首先我们准备三个数据库,分别是:
javaboy_order:订单库,用户创建订单等操作,在这个数据库中完成。
javaboy_ticket:票务库,这个库中保存着所有的票据信息,每一张票都是一条记录,都保存在这个库中。
javaboy_user:用户库,这里保存着用户的账户余额以及付款记录等信息。
每个库中都有各自对应的表,为了操作方便,这些表不用自己创建,将来等项目启动了,利用 JPA 自动创建即可。
3.2 项目概览
我们先来整体上看下这个项目,公众号后台回复 mq_tran 可以下载完整代码:
一共有五个服务:
3.3 注册中心
有人说,都消息驱动了,还要注册中心干嘛?
消息驱动没错,消息驱动微服务之后每个服务只管把消息往消息中间件上扔,每个服务又只管消费消息中间件上的消息,这个时候对于服务注册中心似乎不是那么强需要。不过在我们这个案例中,消息驱动主要用来处理事务问题,其他常规需求我们还是用 OpenFeign 来处理,所以这里我们依然需要一个注册中心。
这里的注册中心我就选择常见的 Eureka,省事一些。由于本文主要是和大家聊分布式事务,所以涉及到微服务的东西我就简单介绍下,不会占用过多篇幅,如果大家还不熟悉 Spring Cloud 的用法,可以在公众号后台回
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。