RocketMQ的消息是怎么丢失的
前言
通过之前文章的阅读,有关RocketMQ的底层原理相信小伙伴们已经有了一个比较清晰的认识。
那么接下来王子想跟大家讨论一个话题,如果我们的项目中引入了MQ,势必要面对的一个问题,就是消息丢失问题,今天我们就来聊聊消息是怎么丢失的。
现在假设我们的业务是这样的,用户通过订单系统下了一个订单,订单系统完成支付后会发送消息给RocketMQ,然后积分系统会从RocketMQ中消费消息,去给用户增加积分,如下图:

但是突然有一天有用户反映,支付订单之后,自己的积分并没有增长,这是为什么呢?
经过排查日志,我们只发现了推送消息给MQ的日志,而没有发现积分系统消费这条消息的日志,这就导致了积分系统并没有给用户发放积分。
也就是说,消息在传输过程中丢失了。
在系统的核心链路中,如果发生消息丢失的问题,可能会产生恶劣的后果,为了解决此类问题,我们必须弄明白什么时候会发生消息丢失。
订单系统推送消息过程中会丢失消息吗?
我们先来看一下整个流程的第一步,订单系统在支付成功之后,一定会把支付成功的消息推送给MQ,那么在这个推送的过程中,消息可能丢失吗?
答案是肯定的,一定会存在消息丢失的情况。
比较常见的情况就是网络抖动,在推送消息这一过程中是通过网络进行通信的,那么这个时候如果恰巧网络出现了故障,导致通信失败了,那么这个消息必然就不会成功的推送到MQ中。
那除了网络抖动外,还有没有其他的情况导致推送失败呢?
其实情况有很多,比如MQ成功接收到了消息,但是MQ本身的网络模块的代码出现了异常,可能是内部实现的bug,导致消息没有成功处理。
或者当我们推送消息给一个MQ的主从集群的时候,刚好遇到Leader节点出现故障,其他的Follower正在尝试切换为Leader,这个过程中也可能导致消息丢失。
类似的问题还有其他的。
所以我们首先要明确一点,无论我们使用任何MQ中间件的时候,你发送出的消息都不一定能成功,而失败的时候有可能会在你的代码里发生异常,也有可能不会抛出异常,具体要看什么情况导致的发送失败。
MQ接收到消息后,自己会把消息弄丢吗?
接下来假设我们订单系统推送到MQ这一过程没有任何问题,消息成功到达了MQ中,此时订单系统会认为消息写入成功了,那么这时候消息就一定不会丢失了吗?
答案是否定的,这个时候也不能保证消息的不丢失,我们来分析一下。
通过之前文章的了解,相信大家都还记得,当消息写入到MQ后,MQ会把消息先写入到os cache,也就是操作系统的缓存区中,本质也是内存,如下图:

也就是说,你认为发送成功的消息,可能只存在于内存中,还没到磁盘中。
那么如果这个时候机器宕机了,os cache中的消息数据将会跟着丢失掉,是不是这个理。
那么现在假设消息已经刷新到磁盘上了,是不是就可以保证万无一失了呢?
显然这个时候也是不能完全保证的,因为虽然你把数据保存到了磁盘中,但是如果磁盘发生了故障,数据还是会丢失掉。
如果大家平时有了解一下新闻热点,会听说过某某互联网公司,由于数据存储在磁盘上没有冗余备份,结果磁盘发生故障导致好多年的核心数据全部丢失,大量工作都功亏一篑,这就是血淋淋的教训。
积分系统消费到了消息就能保证消息的不丢失了吗?
那么到现在,经历了重重困境,假设积分系统终于能够消费到这条消息了,那么它就能安稳的把积分正常的发放给用户吗?
答案依然是否定的。
看过之前文章的小伙伴们应该还记得消费者在进行消费时,是有一个offset的概念的。
这个offset说白了就是个进度标识,让MQ知道消费者消费到了哪,下次好接着向下消费。
现在假设我们有两条消息,offset为1和2。

假设我们的积分系统接收到了消息1,那么消息1就在积分系统的内存中,正要准备给用户发放积分。
而默认情况下,消费者会自动提交已经消费的消息的offset,所以当积分系统获取消息后,可能直接就把消息1的offset提交给了MQ,标识为已经处理了这条消息。
那么此时,如果积分系统突然宕机,还未发放积分给用户,那么这条消息1自然就丢失了,因为MQ已经把他标记成了已处理,实际积分系统还未处理。
所以消费者获得消息后也是可能发生消息丢失的。
总结
好了,看过今天的文章,相信小伙伴们对于RocketMQ的消息是怎么丢失的会有一个更深刻的印象。
总结起来就是以下几点:
1.生产者发送消息到MQ这一过程导致消息丢失
2.MQ自己发生故障导致消息丢失
3.消费者拿到消息后,由于操作不当导致消息丢失
所以任何的技术引入生产环境都是有风险的,引入前我们一定要做好功课。
今天的文章就说到这,小伙伴们可能会问王子,聊了这么多,到底应该如何解决掉消息丢失的问题呢?
别急,我们下篇文章就会有解决方案了。
那么小伙伴们针对MQ的消息丢失问题是怎么解决的呢,欢迎大家留言和王子一起讨论。
往期文章推荐:

RocketMQ的消息是怎么丢失的的更多相关文章
- RocketMQ之消息幂等
幂等(idempotent.idempotence)是一个数学与计算机学概念,常见于抽象代数中. 在编程中一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同. 首先我们了解一下什么是 ...
- rocketmq总结(消息的顺序、重复、事务、消费模式)
rocketmq总结(消息的顺序.重复.事务.消费模式) 参考: http://www.cnblogs.com/wxd0108/p/6038543.html https://www.cnblogs.c ...
- rocketmq总结(消息的高可用、中间件选型)
rocketmq总结(消息的高可用.中间件选型) 参考: https://blog.csdn.net/meilong_whpu/article/details/76922456 http://blog ...
- rocketmq事务消息入门介绍
说明 周五的时候发了篇:Rocketmq4.3支持事务啦!!!,趁着周末的时候把相关内容看了下,下面的主要内容就是关于RocketMQ事务相关内容介绍了. 说明: 今天这篇仅仅是入门介绍,并没有涉及到 ...
- RocketMQ事务消息学习及刨坑过程
一.背景 MQ组件是系统架构里必不可少的一门利器,设计层面可以降低系统耦合度,高并发场景又可以起到削峰填谷的作用,从单体应用到集群部署方案,再到现在的微服务架构,MQ凭借其优秀的性能和高可靠性,得到了 ...
- RocketMQ事务性消息及持久化
TransactionProducer(事务消息): 在分布式系统中,我们时常会遇到分布式事务的问题,除了常规的解决方案之外,我们还可以利用RocketMQ的事务性消息来解决分布式事务的问题.Rock ...
- RocketMQ源码分析之从官方示例窥探:RocketMQ事务消息实现基本思想
摘要: RocketMQ源码分析之从官方示例窥探RocketMQ事务消息实现基本思想. 在阅读本文前,若您对RocketMQ技术感兴趣,请加入RocketMQ技术交流群 RocketMQ4.3.0版本 ...
- RocketMQ 常用消息类型
文章首发于公众号<程序员果果> 地址 : https://mp.weixin.qq.com/s/dYqGd9zi2mNelsNNLIribg 消息发送示例 导入依赖: <depend ...
- RocketMQ源码 — 九、 RocketMQ延时消息
上一节消息重试里面提到了重试的消息可以被延时消费,其实除此之外,用户发送的消息也可以指定延时时间(更准确的说是延时等级),然后在指定延时时间之后投递消息,然后被consumer消费.阿里云的ons还支 ...
随机推荐
- Codeforces1393 题解(A-D)
AC代码 A. Rainbow Dash, Fluttershy and Chess Coloring 可以推导出\(f_1 = 1, f_2 = 2, ..., f_n = f_{n - 2} + ...
- 9.深入k8s:调度器及其源码分析
转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com 源码版本是1.19 这次讲解的是k8s的调度器部分的代码,相对来说比较复杂,慢慢的梳理清 ...
- 一位北漂12年IT工程师的年终总结
Hi,我叫李振良,来自河南周口农村的一个普通家庭,如今来北京已经12年了,我是那种没有大学背景.没有聪明头脑.没有人脉的奋斗青年,但我又是那种不甘于现状,一直想做最好的那个人! 2019年已悄然离去, ...
- 剑指 Offer 19. 正则表达式匹配
题目描述 请实现一个函数用来匹配包含'. '和'*'的正则表达式.模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(含0次).在本题中,匹配是指字符串的所有字符匹配整个模式. ...
- 你会Spring Cloud吗?
如果有人问你这句话,你不要急着回答,因为答语和问者的关系莫大. 如果问你的是个老板或管理者,那么他多半不了解这项技术,很有可能只是知道这个技术名词而已,你知道的一定比他们深,你大可夸夸其谈的.在口若悬 ...
- python基础:用yagmail模块发邮件
一.yagmail模块安装 网上下载的yagmail模块安装以后,在使用过程中,如果附件有中文,会显示乱码. pip install yagmail-0.10.212-py2.py3-none-any ...
- python之读取yaml数据
一.yaml简介 yaml:一种标记语言,专门用来写配置文件. 二.yaml基础语法 区分大小写: 使用缩进表示层级关系: 使用空格键缩进,而非Tab键缩进 缩进的空格数目不固定,只需要相同层级的元素 ...
- oracle之二redo日志
redo 日志 4.1 redo (重做) log 的功能:数据recovery4.2 redo log 特征: 1)记录数据库的变化(DML.DDL) 2)用于数据块的recover ...
- 学习 | iscroll之上拉加载下拉刷新
引入文件顺序 1.zepto 2.iscroll.js 3.scroll-probe.js 链接 完整代码:https://github.com/dirkhe1051931999/writeBlog/ ...
- 分布式系统监视zabbix讲解二之邮件报警通知
概述 在上一篇博客<分布式系统监视zabbix讲解一技术流ken>中已经详细讲解了如何安装zabbix,本篇博客将详细讲解如何使用zabbix监控另外一台主机,并实现email报警通知机制 ...