美文网首页Java
RocketMQ消息丢失解决方案:事务消息

RocketMQ消息丢失解决方案:事务消息

作者: HUC王子 | 来源:发表于2020-10-13 16:26 被阅读0次

    前言

    上篇文章,王子通过一个小案例和小伙伴们一起分析了一下消息是如何丢失的,但没有提出具体的解决方案。

    我们已经知道发生消息丢失的原因大体上分为三个部分:

    1.生产者发送消息到MQ这一过程导致消息丢失

    2.MQ自己发生故障导致消息丢失

    3.消费者拿到消息后,由于操作不当导致消息丢失

    接下来我们就针对第一种情况,聊一聊如何解决生产者发送消息过程中的消息丢失问题。

    先发送half消息到MQ

    针对于这一问题,RocketMQ是自带一套解决方案的,就是事务消息。今天我们就来看一下事务消息的实现流程。

    案例还是上次的案例,当用户通过订单系统下订单支付的时候,在订单支付成功后,会发送消息给MQ,但是这样的流程是无法保证事务性的。

    当我们引入事务消息后,其实订单系统是不会先去执行CRUD的操作的,而是先发送一条half消息给MQ,这个half消息其实就是订单完成支付的消息,你可以理解为它的状态是half状态。

    而积分系统是无法消费half状态的消息的。

    订单系统发送了half消息后就会等待MQ给出成功的响应,如下图:

    图片 18.png

    看到这里有些小伙伴可能会问,为什么要发送half消息呢?

    其实大家可以想一下,假如我们不发送half消息,直接去操作数据库,把订单支付业务走完,然后再去发送消息给MQ,结果发送过程中发生了异常,这就导致了积分系统无法消费到消息,就会导致支付成功,而积分没有发放的情况。

    所以我们先发一条half消息,就是为了先确认一下能否正常发送消息,或者说确认MQ是不是还活着,并且告诉MQ接下来的消息很重要,不能丢失掉。

    half消息写入失败怎么办

    half消息的发送也是可能失败的,可能因为报错、MQ自己挂了、或者网络原因导致消息发送失败。

    那订单系统就会得到这一反馈,接着就应该进行回滚操作,比如订单关闭,退款等操作。

    图片 19.png

    half消息写入成功,并得到响应

    那么假如half消息发送成功,并得到了成功的响应后,订单系统应该怎么做呢?

    这个时候,订单系统就应该去操作数据库,完成自己的业务功能了。

    因为half消息发送成功,表示MQ可以正常接收消息。

    图片 20.png

    half消息写入成功,没有得到响应

    那么假如half消息发送成功,但是没有得到MQ的成功响应,会怎么办呢?

    这个时候,half消息已经正常的存储到了MQ中,但订单系统迟迟不能得到响应,可能会报一些网络超时的错误,订单系统就去执行回滚操作了。

    那么对于这条half消息该怎么处理呢?

    这就要说到RocketMQ的补偿机制了,它会去扫描half消息,如果这条half消息迟迟没有被rollback或者commit,一定时间后就会回调订单系统的一个补偿接口,判断一下这步操作是成功了还是失败了。

    如果成功了,那就重新发送commit消息给MQ,失败了,重新发送rollback消息给MQ。后文会介绍rollback和commit消息。

    数据库操作发生异常

    那么接下来如果订单系统在执行数据库的时候发生了异常怎么办呢?

    这个时候数据库本身是有事务机制的,同时我们再发送一条rollback消息给MQ就可以了。

    这个时候MQ接收到rollback消息后,就会把之前的half消息给作废掉了。

    订单业务完成后

    那么订单系统自己的业务成功完成后接着做什么呢?

    这个时候就要发送一条commit消息给MQ了,让MQ把之前的half消息执行commit操作,之后积分系统就可以看到这条消息了。

    图片 21.png

    rollback或者commit消息发送失败怎么办

    rollback或者commit消息也是可能发送失败的,这个时候其实也很简单。

    上文中我们已经说到了RocketMQ的补偿机制,所以无论订单系统本身是要发送rollback消息还是commit消息,如果发送失败,MQ的补偿机制就会扫描这条half消息,一定时间之后回调订单系统的补偿接口,判断执行是否成功了,然后重新发送消息给MQ就可以了

    总结

    今天我们通过对RocketMQ发送消息这一过程进行各种情况的分析,会发现,开启事务消息流程后,生产者发送消息到MQ这一过程的消息可靠性是可以得到保证的。

    如果有小伙伴觉得有些情况还是没有考虑到,欢迎评论区留言一起讨论。

    下篇文章我们将深入探索一下事务消息的底层实现原理,欢迎小伙伴们围观。

    往期文章推荐:

    RocketMQ的发送模式和消费模式

    讨论一下秒杀系统的技术难点与解决方案

    秒杀系统中的扣减库存和流量削峰

    深入研究RocketMQ生产者发送消息的底层原理

    深入研究Broker是如何持久化的

    Dledger是如何实现主从自动切换的

    深入研究RocketMQ消费者是如何获取消息的

    RocketMQ的消息是怎么丢失的

    相关文章

      网友评论

        本文标题:RocketMQ消息丢失解决方案:事务消息

        本文链接:https://www.haomeiwen.com/subject/phwvpktx.html