前言

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

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

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

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

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

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

先发送half消息到MQ

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

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

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

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

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

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

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

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

half消息写入失败怎么办

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

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

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

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

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

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

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操作,之后积分系统就可以看到这条消息了。

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

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

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

总结

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

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

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

往期文章推荐:

RocketMQ的发送模式和消费模式

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

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

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

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

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

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

RocketMQ的消息是怎么丢失的

RocketMQ消息丢失解决方案:事务消息的更多相关文章

  1. RocketMQ消息丢失解决方案:同步刷盘+手动提交

    前言 之前我们一起了解了使用RocketMQ事务消息解决生产者发送消息时消息丢失的问题,但使用了事务消息后消息就一定不会丢失了吗,肯定是不能保证的. 因为虽然我们解决了生产者发送消息时候的消息丢失问题 ...

  2. Apache RocketMQ 正式开源分布式事务消息

    近日,Apache RocketMQ 社区正式发布4.3版本.此次发布不仅包括提升性能,减少内存使用等原有特性增强,还修复了部分社区提出的若干问题,更重要的是该版本开源了社区最为关心的分布式事务消息, ...

  3. 消息队列之事务消息,RocketMQ 和 Kafka 是如何做的?

    每个时代,都不会亏待会学习的人. 大家好,我是 yes. 今天我们来谈一谈消息队列的事务消息,一说起事务相信大家都不陌生,脑海里蹦出来的就是 ACID. 通常我们理解的事务就是为了一些更新操作要么都成 ...

  4. rocketmq事务消息入门介绍

    说明 周五的时候发了篇:Rocketmq4.3支持事务啦!!!,趁着周末的时候把相关内容看了下,下面的主要内容就是关于RocketMQ事务相关内容介绍了. 说明: 今天这篇仅仅是入门介绍,并没有涉及到 ...

  5. RabbitMQ,RocketMQ,Kafka 事务性,消息丢失和消息重复发送的处理策略

    消息队列常见问题处理 分布式事务 什么是分布式事务 常见的分布式事务解决方案 基于 MQ 实现的分布式事务 本地消息表-最终一致性 MQ事务-最终一致性 RocketMQ中如何处理事务 Kafka中如 ...

  6. 分布式开放消息系统RocketMQ的原理与实践(消息的顺序问题、重复问题、可靠消息/事务消息)

    备注:1.如果您此前未接触过RocketMQ,请先阅读附录部分,以便了解RocketMQ的整体架构和相关术语2.文中的MQServer与Broker表示同一概念 分布式消息系统作为实现分布式系统可扩展 ...

  7. RocketMQ系列(七)事务消息(数据库|最终一致性)

    终于到了今天了,终于要讲RocketMQ最牛X的功能了,那就是事务消息.为什么事务消息被吹的比较热呢?近几年微服务大行其道,整个系统被切成了多个服务,每个服务掌管着一个数据库.那么多个数据库之间的数据 ...

  8. RocketMQ源码详解 | Broker篇 · 其四:事务消息、批量消息、延迟消息

    概述 在上文中,我们讨论了消费者对于消息拉取的实现,对于 RocketMQ 这个黑盒的心脏部分,我们顺着消息的发送流程已经将其剖析了大半部分.本章我们不妨乘胜追击,接着讨论各种不同的消息的原理与实现. ...

  9. RocketMQ事务消息实现分析

    这周RocketMQ发布了4.3.0版本,New Feature中最受关注的一点就是支持了事务消息: 今天花了点时间看了下具体的实现内容,下面是简单的总结. RocketMQ事务消息概要 通过冯嘉发布 ...

随机推荐

  1. File类与IO流

    一.File类与IO流 数组.集合等内容都是把数据放在内存里面,一旦关机或者断电,数据就会立刻从内存里面消失.而IO主要讲文件的传输(输入和输出),把内存里面的数据持久化到硬盘上,如.txt .avi ...

  2. Python - 网易邮箱邮件阅读和删除辅助小脚本

    摘要:[原创]转载请注明作者Johnthegreat和本文链接 简介:在Windows下的网易邮箱大师客户端中,阅读邮件时,可以使用快捷键Delete删除邮件,然后自动跳到下一封,如果再按一次Dele ...

  3. python基础一(安装、变量、循环、git)

    一.开发语言分类 系统的开发语言有java.c++.c#.python.ruby.php等等,开发语言可分为编译型语言和解释型语言. 编译型语言就是写好代码之后就把代码编译成二进制文件,运行的时候运行 ...

  4. oracle之insert语句总结

    insert语句总结 16.1 第一类,insert语句:单行插入 1)SQL> create table a (id int,name char(10) default 'aaa');   / ...

  5. 吴恩达《深度学习》-课后测验-第一门课 (Neural Networks and Deep Learning)-Week 4 - Key concepts on Deep Neural Networks(第四周 测验 – 深层神经网络)

    Week 4 Quiz - Key concepts on Deep Neural Networks(第四周 测验 – 深层神经网络) \1. What is the "cache" ...

  6. 工具类-Fastjson入门使用

    简介 什么是Fastjson? fastjson是阿里巴巴的开源JSON解析库,它可以解析JSON格式的字符串,支持将Java Bean序列化为JSON字符串,也可以从JSON字符串反序列化到Java ...

  7. [LeetCode]1071. 字符串的最大公因子(gcd)

    题目 对于字符串 S 和 T,只有在 S = T + ... + T(T 与自身连接 1 次或多次)时,我们才认定 "T 能除尽 S". 返回最长字符串 X,要求满足 X 能除尽 ...

  8. Java知识点JUC总结

    JUC:java.util.concurrent (Java并发编程工具类) 一般面试提问:面向对象和高级语法.Java集合类.Java多线程.JUC 和高并发.Java IO和 NIO 获取多线程的 ...

  9. 学习 | 基于require.js的三级联动菜单【入门】

    主要目的是学习如何使用require.js AMD就是通过延迟和按需加载来解决各个模块的依赖关系,其中require就是AMD的框架之一 它的优点是可以解决以下问题: JS文件的依赖关系. 通过异步加 ...

  10. 复习 | 彻底弄懂Flexbox之Demo篇

    flexbox之前有接触,写项目时也用过,但也只是简单的,对其也是似懂非懂,所以今天下定决心把这个再学一遍,因为似懂非懂就是不懂 本文主要是的demo演示,想看flexbox语法 请移步flexbox ...