rabbitmq死信队列消息离奇失踪

问题是这样的,在程序里创建了延时队列,创建之后在页面随便点个查询按钮,mq 死信队列消息离奇失踪,不点页面的查询按钮则无事,图如下所示,希望大师帮我看看,公司项目,急!!

img

img

img

延时队列使用redis实现了。。

建议如下角度排查:
1.消息是否会持久化到磁盘
2.是否是有时限的消息
3.是否有没有发现的消费端在消费消息,按照项目经验,这个概率很高
4.建议同步检测一下rabbitmq的日志信息

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 帮你找了个相似的问题, 你可以看下: https://ask.csdn.net/questions/7703808
  • 我还给你找了一篇非常好的博客,你可以看看是否有帮助,链接:rabbitmq保证消息不重复消费,消息不丢失,消息积压问题处理
  • 您还可以看一下 IT熊猫学院老师的RabbitMQ消息中间件实战(附讲义和源码)课程中的 工作队列模式-公平分发小节, 巩固相关知识点
  • 除此之外, 这篇博客: RabbitMQ总结中的 消费者的消息应答策略有哪些?MQ如何将消息可靠投递到消费者?(防止队列到消费者的消息丢失)消息被拒绝后会怎么样? 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:

    消息应答就是:消费者在接收到消息并且处理该消息之后,告诉 rabbitmq 它已经处理了,rabbitmq 可以把该消息删除了。防止队列到消费者的消息丢失

    1. MQ将消息push给Client(或Client来pull消息)
    2. Client得到消息并做完业务逻辑
    3. Client发送Ack消息给MQ,通知MQ删除该消息,此处有可能因为网络问题导致Ack失败,那么Client会重复消息,这里就引出消费幂等的问题;
    4. MQ将已消费的消息删除。

    自动应答,默认策略,autoAck = true

    • 如果配置的是自动应答,那么消息发送后立即被认为已经传送成功,如果程序这时候突然宕机,那么消息直接丢失,这是很不安全的。
    • 不论乎消费者对消息处理是否成功,都会告诉队列删除消息。

    手动应答:设置手动应答,autoAck = false

    • 确认应答:channel.basicAck(用于肯定确认)RabbitMQ 已知道该消息并且成功的处理消息,可以将其丢弃
    • 拒绝应答一:channel.basicNack() (用于否定确认),三个参数
    • 拒绝应答二:channel.basicReject() (用于否定确认),两个参数
    channel.basicConsume(QUEUE_NAME,false,
    	(consumerTag, message) -> {
    	    // 接收到的消息
    	    String receviedMessage = new String(message.getBody());
    	    System.out.println("消费者接收到的消息:"+receviedMessage);
    	    /**
    	     * 确认应答
    	     *  1.哪个消息
    	     *  2.应答一个消息还是应答一个消息
    	     *      true: 把当前消息和之前的消息一起应答
    	     *      false: 只应答当前消息
    	     */
    	    // channel.basicAck(message.getEnvelope().getDeliveryTag(),false);
    	    /**
    	     * 拒绝 确认受到应答
    	     *  1.哪个消息
    	     *  2.应答一个消息还是应答一个消息
    	     *      true: 把当前消息和之前的消息一起拒绝
    	     *      false: 只拒绝当前消息
    	     *  3.是否重新入队
    	     *      true: 消息重新入队
    	     *      false: 丢弃消息 或者 进入死信队列(死信队列需要配置)
    	     */
    	    // channel.basicNack(message.getEnvelope().getDeliveryTag(),false,false);
    	    /**
    	     * 拒绝 确认受到应答
    	     *  1.哪个消息
    	     *  2.是否重新入队
    	     *      true: 消息重新入队
    	     *      false: 丢弃消息 或者 进入死信队列(死信队列需要配置)
    	     */
    	    channel.basicReject(message.getEnvelope().getDeliveryTag(),false);
    	},
    	(consumerTag) -> {
    	    System.out.println("消费失败");
    	});
    

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^