RocketMQ中各类重复消费的原理浅析

随着大数据和云计算时代的到来,我国的各个产业每天都在产生不可估计的数据,以及对数据的各式各样的需求,消息中间件在处理数据、消费数据的过程中越来越受到重视。在高并发、微服务、分布式的场景下,如何合理地利用消息中间件,如何保证MQ消费消息的幂等性?所谓知其然,才能知其所以然,本文将通过RocketMQ作为例子,来扒一扒什么情况下会导致重复消费。

作者:李佳斌

单位:中国移动智慧家庭运营中心

Part01●RocketMQ如何生产和消费消息●

先简单介绍下RocketMQ正常生产消息和消费消息的流程,如下图。

1.生产者在发送消息之前根据负载均衡策略(默认是轮询)选择一个Queue,然后跟这个Queue所在的机器建立连接,把消息发送到这个Queue上。

2.消费者消费这个Queue,就能获取到对应的消息。

-问题出现

当异常情况出现时,如消息发送超时或者消息消费超时,RocketMQ为保证消息发送成功,会启动重试机制,选择另一台机器的Queue重发。现在假设有这样一种情况,消费者实际正确接收到了消息,只是由于网络波动导致响应超时了,那就会出现消息重复发送,导致消费者重复消费的情况出现。

那除此之外,还有没有其他情况会导致消息重复消费的情况呢?总结起来一共有如下几种情况。

1)消息发送异常时的重复消费

2)消费消息时抛出了异常

3)消费者提交offset失败

4)Broker持久化offset失败

5)主从同步失败

6)重平衡

Part02●浅析各类情况●

-消费消息时抛出异常

问题分析一

RocketMQ在并发消费的模式下会调用MessageListenerConcurrently的consumeMessage方法,入参是msgs集合。当调用该方法消费消息出现异常时,返回的结果status就会是null。这种情况下会导致status被设置为RECONSUME_LATER,也就是说消息之后会被重复消费。

问题分析二

传入的是msgs集合。上述原因一中消息处理之后,不管成功失败,都会对结果进行处理。而集合中的任意一个失败,都会导致status被设置为RECONSUME_LATER。在对结果处理是,判断到RECONSUME_LATER时,就会对msgs重新遍历并发送消息,重新消费,从而导致之前成功处理的消息都会被重复消费。不过好在msgs消息的数量默认情况下是1。

-消费者提交offset失败

何为offset

producer发送消息到broker,Rocketmq会将消息的内容持久化到commitLog文件中,再分发到topic下的消费队列consumeQueue,消费者提交消费请求时,broker从该consumer负责的消费队列中根据请求参数传入的起始offset来获取需要消费的消息索引信息,再从commitLog中获取具体的消息内容返回给consumer。消费成功之后,消费者提交offset,来记录这个queue消费到哪个位置了。

问题分析

RocketMq设计的时候,消费完消息,并不是同步提交offset,而是将offset保存到内存中,通过一个定时任务(默认是5S一次),以网络请求的方式将offset提交给broker。如果最新的offset还没提交,此时服务器宕机了,那么重启之后,就会从broker中读取到之前的提交的offset,并从此处开始消费,此时就会出现重复消费的情况了。

-broker持久化offset失败

与消费者提交offset同理,Broker为了防止数据丢失,会将offset持久化到磁盘中。同样的也是通过一个默认5S的定时任务来处理持久化操作。所以offset的完整过程就如下图。当broker宕机时,就会导致offset丢失,此时如果消费者重新拉取消费进度,就会比实际消费的进度要低,导致重复消费。

-主从同步失败

为保证RocketMQ服务的高可用,一般项目中都会启用主从备份的模式,当主节点挂掉之后,从节点就会升级为主节点对外提供服务。因此就需要进行主从同步,保证数据的一致性。默认情况下每隔10S,从节点会向主节点请求,同步元数据,包括消费进度。此时如果主节点宕机了,从节点就无法获取到10S之内的消费进度,自然也就会导致重复消费。

-重平衡

何为重平衡

RocketMQ的消费者有两种模式,集群消费模式和广播消费模式,绝大多数场景采用的都是集群消费模式。前面提到的消费进度就是在集群消费模式下才会存在。集群消费模式中有一个消费组的概念。一个消费组可以有多个消费者,不同消费组之间消费消息互不干扰,而同一消费组的消费者按照一定的算法分配消息队列进行消息消费,保证一个消息只能被一个消费组消费一次。当消费组中的消费组增加或者减少时就会触发重平衡。如图,原先消费组中有两个消费者,平均消费4个队列,每个消费组2个队列;当加入了一个新的消费者时,为了保证新的消费者能够消费消息,就会进行重平衡,重新分配消息队列。

假设在重平衡发生时,此时消费者2还在正常消费Queue4,当消费者3加入,重平衡完成时,此时消费者2判断到Queue4已经不属于自己消费了,就会将Queue4设置为dropped,消费完成时,发现队列是dropped状态,那么消费者2的消费进度offset就不会被提交。成功消费了消息,但是消费进度却没有被提交,于是当消费者3开始消费消息时,就会从服务端拉取到之前的消费进度,造成队列4的消息被重复消费。

清理机制讲解

Part03●总结●

RocketMq的官方文档中对消息传递有这样的解释:RocketMq确保所有消息至少被传递一次,在大多数情况下,消息不会重复。可见RocketMq为了保证消息的不丢失,牺牲了消息投递的重复率。因此我们在使用RokcetMq时需要合理使用它的特点,设计合理的幂等技术方案来解决重复消费的问题。

THE END
1.别让先用后付成了消费陷阱付成新浪财经先用后付是指消费者无需提前支付钱款、零元下单即可体验商品,满意后再付款的一种授信赊购服务。消费者在不知情的情况下被开通先用后付,有时只是想收藏商品或先添加到购物车却变为直接下单,如此一来,可能因未在规定时间内付款而产生逾期费用及征信问题。此外,消费者无需输入支付密码就能直接下单,也可能因此出现过...http://finance.sina.com.cn/jjxw/2024-11-13/doc-incvwfmt5646472.shtml
2.如何避免重复消费陷阱?重复消费是一个普遍存在的问题,不仅会造成个人财务负担,也会对整个社会经济产生不利影响。那么,如何避免陷入重复消费的陷阱呢?下面我们就来探讨一下这个问题。 明确需求,合理消费 在进行消费之前,我们首先要明确自己的实际需求。很多人容易受广告或者周围人的影响,盲目地进行消费,结果往往是买到不需要的东西。因此,我们...https://life.yxlady.com/consume/202408/789385.shtml
3.Kafka如何保证消息的消费顺序Kafka如何保证消息不被重复消费...Kafka如何保证消息不被重复消费生产者消息重复发送 生产发送的消息没有收到正确的broke响应,导致producer重试。 详解:producer发出一条消息,broker落盘以后,因为网络等原因,发送端得到一个发送失败的响应或者网络中断,然后producer收到 一个可恢复的Exception重试消息导致消息重复。 解决:enable.idempotence=true //此时会...https://www.dtstack.com/bbs/article/19475
4.公务卡知识问答5、遇到商户不具备刷卡条件怎么办? 答:我市规定,在公务卡结算方式的适用范围内,行政事业单位应优先在具有刷卡条件的商户进行公务消费,其中市直单位原则上只在具有刷卡条件的商户进行公务消费。对确实不具备刷卡条件的公务消费活动,单位职工应先行垫付现金完成交易,在报销时单位财务部门将款项支付至职工的工资卡账户,不得...http://www.wancheng.gov.cn/sitesources/wcqczj/page_pc/tzgg/article50f4cb55dcd144318566e4675a1b7e3b.html
1.如何确保消费行为的合理性和安全性?这种合理性和安全性如何进行衡量...储蓄和债务状况:合理的消费行为应该能够保证有一定的储蓄,以应对突发情况或未来的规划。同时,要控制债务水平,避免过度负债导致财务困境。 消费满意度:消费后对所购买的产品或服务是否满意也是衡量消费合理性和安全性的重要指标。如果频繁出现不满意的情况,可能意味着消费决策存在问题。 https://stock.hexun.com/2024-11-10/215455561.html
2.降随e保重大疾病保险购买攻略阳光保险集团官方网站23、如果购买时出现“交易流水重复”,导致无法支付怎么办? 为了保证您的资金不会重复扣款,登录进会员中心,删除待支付订单,重新进行购买即可。 24、健康随e保的保费多少钱? 每个人按照不同的保额、年龄不同等,有较大的区别,您可按照自己的情况点击“保费计算”计算。 https://www.sinosig.com/page/common/prdt/html/130922.shtml
3.Alibaba最新1000多道Java面试题汇总详解,收藏起来慢慢刷!9、如何确保消息不丢失? 10、消息基于什么传输? 11、如何保证消息的顺序性 12、Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什么区别? 13、Fanout(广播分发)? 14、如何保证高可用的? 15、mq 的缺点 16、如何保证消息的可靠传输?如果消息丢了怎么办 17、如何避免消息重复投递或重复消费? https://maimai.cn/article/detail?fid=1728969401&efid=esjJLvGGL4fAr1LArgq_cQ
4.消息队列消费失败消息队列重复消费原因消息队列 消费失败 消息队列重复消费原因 1、如何保证消息不被重复消费? 一、为什么会出现重复消费的问题? RabbitMQ、RocketMQ、Kafka 都有可能出现重复消费的问题,导致重复消费的原因可能出现在生产者,也可能出现在 MQ 或 消费者。这里说的重复消费问题是指同一个数据被执行了两次,不单单指 MQ 中一条消息被消费...https://blog.51cto.com/u_16213586/9670405
5.面试官:RocketMQ如何保证消息不丢失,如何保证消息不被重复消费?先消费,消费成功后再提交; 思路一可以解决重复消费的问题但是会丢失消息,因此Rocketmq默认实现的是思路二,由各自consumer业务方保证幂等来解决重复消费问题。 手段七:消费消息重试机制 当消费消息失败了,如果不提供重试消息的能力,则也不能算完全的可靠消费,因此RocketMQ本身提供了重新消费消息的能力。 https://cloud.tencent.com/developer/article/2085783
6.如何保证消息不被重复消费?或者说,如何保证消息消费的幂等性...消费者处理消息失败:当消费者处理消息失败时,可能会导致消息没有被确认,从而出现重复消费的问题。 为了避免这些问题,我们需要采取一些措施来保证消息的可靠性,例如手动确认消息、消费者自身保证幂等性等。 3. 如何保证消息不被重复消费? 在MQ 中,消息的消费是异步的,消费者需要从队列中获取消息并进行处理。 https://www.nowcoder.com/discuss/522882458006618112
7.汽车电话销售话术5、客户要求与车型卖点或定位不符,怎么办? 引导需求 你要引导顾客需求甚至超越顾客需求。想想“和尚买梳”、“非洲卖鞋”,你就会明白这个道理。虽然现在汽车消费越来越崇尚个性,但依然摆脱不了汽车消费群体的“从众心理”,消费者不是专家,而你自己要树立专家形象,形成“权威效应”。 https://mip.jy135.com/zhichang/299913.html
8.公务卡知识问答33、因公务卡还款不及时而产生的循环利息和滞纳金,应由谁负担? 34、怎样避免公务卡还款不及时的问题? 35、如何查询公务卡报销是否已完成? 36、如果遗失了公务卡怎么办? 37、如果使用公务卡进行个人消费,能够保证消费信息的私密性吗? 38、如何获取短信息提示服务? https://caiwu.glut.edu.cn/info/1025/1069.htm
9.薛兆丰经济学课认真做下的笔记利息是对人们延迟消费,接受不确定性的一种补偿 商品紧俏是现货,如果可预见的未来有大量同样的商品补充,那囤货就是自杀;如果未来充满了不确定性,囤起来慢慢销售对社会更有利 23、价格管制 民间借贷不得超过银行利率的4倍,即不得超过24% 根据《合同法》、《最高人民法院关于审理民间借贷案件适用法律若干问题的规定》...https://www.douban.com/doubanapp/dispatch?uri=%2Fnote%2F860309728%3F%26
10.酒店服务礼仪标准8篇(全文)以顾客利益为重,为顾客创造更高消费价值,是酒店全体成员的共同职责。特殊服务的提供,有时涉及几个部门。只有沟通渠道畅通,各部门鼎立合作,才能保证服务的及时、有效提供。管理人员应建立明确的沟通和协作制度,增强部门间理解、上下级沟通,奖励内部服务激励协作精神,使协调工作成为各部门各成员的共同行为准则。 https://www.99xueshu.com/w/file2yyuwrp3.html
11.大数据培训Flink面试知识分享至少一次语义: barrier不对齐,会重复消费。如果不对齐,那么在 chk-100 快照之前,已经处理了一些 chk-100 对应的 offset 之后的数据, 当程序从 chk-100 恢复任务时,chk-100 对应的 offset 之后的数据还会被处理一次, 所以就出现了重复消费。 4. Savapoint了解多少? https://blog.itpub.net/70010293/viewspace-2884751/
12.Kafka中怎么保证消息不会丢失和不重复消费?consumer 采用 pull(拉) 模式从 broker 中读取数据。这个过程只涉及到了服务器和消费者两方,那消费者是怎么保证不丢失和不重复的获取消息呢? 关键在于consumer会维护一个offset,该offset实时记录着自己消费的位置。同时消费者能见到的最大的 offset,是HW, 是ISR 队列中最小的 LEO【这一点看1.3】,所以只要保证off...https://blog.csdn.net/qq_40322236/article/details/127222115
13.小本创业方法任何创业的成功案例,都可以找出更多失败的案例来反证。同样的项目,差不多的团队,操盘手法相仿,甚至办公都在楼上楼下。但是最终的结果可能南辕北辙,这就是艺术的魅力。成功是99%的努力+1%的运气,但是这1%的运气比99%的努力都要重要的多。谋事在人,成事在天。谋只是让成功的概率大一点,但是不保证一定会成功。https://www.yjbys.com/chuangye/zhidao/ruhechuangye/634661.html
14.大学生调查报告集锦15篇(3)动因分析。主要在于消费者自己的选择,其次抒告宣传,然后是亲友介绍,最后才是营业员推荐。不难发现,怎样吸引消费者的注意力,对于企业来说守键。 (二)饮食类产品的`消费情况。 本次调查主要针对一些饮食消费场所和消费者比较喜欢的饮食进行,调查表明,消费有以下几个重要特点: ...https://www.unjs.com/fanwenwang/dcbg/20221127152225_6024906.html