rabbitmq 一次消息丢失问题查找过程

本文深入探讨了RMQ消息队列中消息丢失的原因,包括持久化配置、消息落盘时机以及重试机制的细节。分析了消费者消费失败、消息状态变化和DeadLetterExchanges机制的影响。

问题描述:
rmq消息队列中接收到了消息,并由消费者消费,由于下游服务异常,导致异常抛出,消费者消费消息失败,导致消息一直处于unack,return给rmq-server,重新被消费,但消费失败多次后,不再给消费者(日志中后续没有再打印关于该消息的消费start日志,且始终无end日志),并且队列中没有该消息。
分析:
1、可能未做持久化
2、消费失败,导致不再重试,放入别的地方(maybe是rmq某种机制)

 

一、消息持久化(时机:内存紧张、消息中强制要求)

队列持久化、message持久化、exchange持久化

1.queue设置为durable=true
2.message的deliveryMode=2,这里的deliveryMode=1代表不持久化,deliveryMode= 2代表持久化。
3.另外,exchange也需要持久化,但是,如果不持久化,broker重启后,exchange将不存在,producer就无法正常发送消息,故exchange设置成持久化,同样,durable=true。
这才算持久化完成。

做了持久化配置,仍不能保证消息不会丢失。

首先,consumer角度看,若autoAck=true,接受消息后,没来得及处理就crash掉(此段未验证)
其次,消息的落盘需要有一个时间,一般是25毫秒,才能刷进去
落盘时机,一个一兆大小的buffer,满了,写入文件(不是磁盘),有一个timeout=25ms,不论buffer满不满,buffer和文件内容都会刷到磁盘。
so,25ms内,若消息来了,未到刷盘时机,会导致消息丢失。

这仅仅是持久化的办法。


若可靠的办法,就是设置集群,主从。以及消息确认机制(事务+confirm)

目前来看,我们的持久化均以配置,现象上看,已经发送了多次消息给消费者消费,故已经超过25ms落盘时间,丢失消息原因不太可能是消息未落盘。

二、重试机制 (重试次数达到后,不再被消费)

spring rmq的重试机制我们项目中并未配置,且通过测试,会无限次重试。

以上测试在项目版本和rmq版本均与测试环境一致前提下进行。

 

总结:

持久化未落盘及可能的Dead Letter Exchanges机制均验证,且kill进程等均未复现,后续继续观察。

另外,附上可能的情况:

msg进入rabbitmq-server后,根据是否是持久化消息,可能会有以下几种状态:

%% Definitions:
%% alpha消息本身和消息位置索引都只在内存中
%% beta:  消息本身存储在磁盘中,但是消息的位置索引存在内存中
%% gamma消息本身存储在磁盘中,但是消息的位置索引存在内存中和磁盘中
%% delta消息本身和消息的位置索引都值存储在磁盘中

消息队列内部有BQ(backing_queue)的概念,用来区分不同的消息,如下:

 

rmq

其中Q1、Q4只包含alpha状态的消息,Q2和Q3包含Beta和gamma状态的消息,Delta只包含delta状态的消息。

也就是,当msg是持久化的消息类型时,在rmq-server中,msg可能处于delta、gamma、beta的状态。

且在日志中,查找到warning rabbitmq rebuilding indices from scratch消息,源码中,该日志的打印说明如下:

%% if we found crashed compactions we trust neither the
%% file_summary nor the location index. Note the file_summary is
%% left empty here if it can't be recovered.

所以,对于持久化的消息,在机器重启时,若消息处于beta状态,那么内存中的消息索引将丢失,导致disk中的msg无法被找到,出现消息”丢失“。

 

参考资料:

博客:

https://blog.youkuaiyun.com/zhousenshan/article/details/78681968

https://www.cnblogs.com/163yun/p/9154332.html

https://www.jianshu.com/p/19e0927315da

https://blog.youkuaiyun.com/yeweiouyang/article/details/74943278

官方文档:

ttp://www.rabbitmq.com/persistence-conf.html

http://www.rabbitmq.com/dlx.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值