Spring MessageListener引发异常时,RabbitMQ侦听器停止侦听消息

Spring MessageListener引发异常时,RabbitMQ侦听器停止侦听消息,spring,rabbitmq,spring-amqp,spring-rabbit,Spring,Rabbitmq,Spring Amqp,Spring Rabbit,我正在使用Spring AMQP处理RabbitMQ中的消息以下是问题: 1.(假设)RabbitMQ中有3条消息处于就绪状态 2.第一个由MessageListener拾取并开始处理。(比如)它最终抛出一个异常 3.在这种情况下,容器保持打开状态,但在我重新启动容器之前,其余2条消息不会被处理。同时,第一条消息保持未确认状态。 这是预期的行为吗?如果没有,如何确保在第一条消息处理失败的情况下处理其他两条消息 MQ配置: <rabbit:connection-factory id="con

我正在使用Spring AMQP处理RabbitMQ中的消息

以下是问题:
1.(假设)RabbitMQ中有3条消息处于就绪状态
2.第一个由MessageListener拾取并开始处理。(比如)它最终抛出一个异常
3.在这种情况下,容器保持打开状态,但在我重新启动容器之前,其余2条消息不会被处理。同时,第一条消息保持未确认状态。

这是预期的行为吗?如果没有,如何确保在第一条消息处理失败的情况下处理其他两条消息

MQ配置

<rabbit:connection-factory id="connectionFactory" host="localhost" username="guest" password="guest" /> 

<rabbit:admin connection-factory="connectionFactory" />

<rabbit:listener-container
    connection-factory="connectionFactory" 
    concurrency="1"
    acknowledge="auto">
    <rabbit:listener queue-names="testQueue" ref="myProcessorListener " />
</rabbit:listener-container>
public class MyProcessorListener implements MessageListener{
....
    @Override
public void onMessage(Message message) {
try{
...Some logic...

} catch (Exception e) {
  throw new RuntimeException(e.getMessage(), e);
}

消息被一次又一次地重新传递;为了拒绝它(并丢弃或路由到死信队列),您需要抛出
AmqpRejectAndDontRequeueException
,或者将容器的
requeue rejected
属性设置为
false
。使用Java进行配置时,会弹出
defaultrequeuer

您还可以使用自定义错误处理程序


仅此而已。

消息被一次又一次地重新发送;为了拒绝它(并丢弃或路由到死信队列),您需要抛出
AmqpRejectAndDontRequeueException
,或者将容器的
requeue rejected
属性设置为
false
。使用Java进行配置时,会弹出
defaultrequeuer

您还可以使用自定义错误处理程序


仅此而已。

重新发送邮件是我所期望的。但我担心的是,当一条消息被拒绝时,为什么侦听器没有处理队列中准备好的其他消息。RabbitMQ会在队列的开头重新查询被拒绝的消息,因此如果您只有
concurrency=“1”
,它将被重新处理(并首先被拒绝)。您还可以从默认值(1)增加
预回迁
,以便在收到拒绝之前将其他消息发送给消费者。感谢您的回复。我在MessageListener[onMessage()方法内部]中放置了一个断点。拾取第一条消息时,将执行断点。在此之后,我收到失败消息,消息仍处于“未确认”状态[我在RabbitMQ控制台上检查它]。如果您说消息在队列的最前面重新排队并再次得到处理,那么我的断点应该再次执行,消息也应该从“未确认”状态移动到“准备就绪”状态。我的代码似乎有问题。你能让我知道我做错了什么吗?通常情况下,这样的情况是由于线程卡在用户代码中造成的。在大多数情况下,为
org.springframewrk.amqp
启用调试或跟踪日志记录将显示大量调试消息。如果您没有看到这样的消息,这意味着线程被卡在某个地方(通常在用户代码中)。在这种情况下,进行线程转储以查看发生了什么。如果您仍然无法理解,请发布调试日志并在某处完成线程转储(如github gist或pastebin)。感谢您的帮助。我没有在异常情况下释放锁,因为异常会阻止它。它现在工作正常。我所期望的就是消息被重新传递。但我担心的是,当一条消息被拒绝时,为什么侦听器没有处理队列中准备好的其他消息。RabbitMQ会在队列的开头重新查询被拒绝的消息,因此如果您只有
concurrency=“1”
,它将被重新处理(并首先被拒绝)。您还可以从默认值(1)增加
预回迁
,以便在收到拒绝之前将其他消息发送给消费者。感谢您的回复。我在MessageListener[onMessage()方法内部]中放置了一个断点。拾取第一条消息时,将执行断点。在此之后,我收到失败消息,消息仍处于“未确认”状态[我在RabbitMQ控制台上检查它]。如果您说消息在队列的最前面重新排队并再次得到处理,那么我的断点应该再次执行,消息也应该从“未确认”状态移动到“准备就绪”状态。我的代码似乎有问题。你能让我知道我做错了什么吗?通常情况下,这样的情况是由于线程卡在用户代码中造成的。在大多数情况下,为
org.springframewrk.amqp
启用调试或跟踪日志记录将显示大量调试消息。如果您没有看到这样的消息,这意味着线程被卡在某个地方(通常在用户代码中)。在这种情况下,进行线程转储以查看发生了什么。如果您仍然无法理解,请发布调试日志并在某处完成线程转储(如github gist或pastebin)。感谢您的帮助。我没有在异常情况下释放锁,因为异常会阻止它。现在工作正常了。