【问题标题】:Spring AMQP stuck queue due to unack'd message由于未确认的消息,Spring AMQP 卡住了队列
【发布时间】:2024-08-05 04:45:02
【问题描述】:

我正在使用 SimpleMessageListenerContainer 并且遇到问题,即每隔一小时左右队列就会卡住,并且由于未确认的消息而不会处理任何内容。

我确定这是由于未正确捕获但无法追踪问题的错误所致。

我已将确认模式设置为 NONE,这“修复”了问题,但实际上只是隐藏了问题。此外,如果我想抛出 AmqpException 并将消息重新排队,这在确认模式设置为 NONE 时不起作用。

我的问题是如何跟踪队列卡住的问题,有没有办法查看未确认消息的有效负载?或者是否有一种确认模式允许不需要确认但如果抛出异常则重新排队消息?

这是我注册监听器的方式:

final SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.setQueueNames(queueName);
container.setMessageListener(new MQMessageListenerWrapper(listener));
container.setAcknowledgeMode(AcknowledgeMode.NONE);
container.start();

谢谢。

【问题讨论】:

  • 你试过channel-transacted="true"吗?
  • 如果您共享配置以重现问题,那就太好了。
  • 问题是我无法在本地环境中重新创建它,即使我推送相同的消息!我已经用代码示例更新了问题。

标签: java spring rabbitmq spring-amqp


【解决方案1】:

我最好的猜测是您的消费者线程挂在侦听器上游的某个地方。当控制权返回给容器时,消息被确认或拒绝;如果线程返回容器,它不能处于未确认状态。

使用jstack <pid> 找出消费者线程卡住的位置。

你是对的 NONE 只是在掩盖问题。

【讨论】:

    【解决方案2】:

    当队列卡住时,查看监听特定队列的连接。可能是某种死锁情况的迹象,因为 2 个(或更多)消费者线程在同一个队列上侦听 - 因此被兔子阻塞。

    【讨论】:

    • 我有 2 个应用程序正在添加到队列中,还有 2 个应用程序从队列中读取。我看不到任何死锁或它们如何发生。我有其他应用程序似乎没有这个问题,这就是为什么我认为可能有一个我没有看到的异常并导致确认没有发生。
    【解决方案3】:

    这是我的代码中的一个问题,我最终找到了它,因为它只发生在极少数情况下。

    这与 Spring AMQP 或 RabbitMQ 无关,只是我的错误编码 :-)

    【讨论】:

    • 究竟是什么问题?我也面临同样的情况。
    • @Ashim 那是 6 年前的事了,但我认为这是因为当它通过代码的某个路径时没有确认消息,所以总是卡在同一条消息上。
    最近更新 更多