Java Spring RabbitListener在发送消息后调用方法

Java Spring RabbitListener在发送消息后调用方法,java,spring,rabbitmq,spring-amqp,spring-rabbit,Java,Spring,Rabbitmq,Spring Amqp,Spring Rabbit,在我的接收器处理了特定数量的消息之后,我需要停止Rabbit侦听器并调用一个方法,然后再次启用侦听器 @RabbitListener(...) public void sink(Message msg) { processMsg(); if (condition) { rabbitListenerEndpointRegistry.stop(); doTask(); rabbitListenerEndpointRegistry.st

在我的接收器处理了特定数量的消息之后,我需要停止Rabbit侦听器并调用一个方法,然后再次启用侦听器

@RabbitListener(...)
public void sink(Message msg) {
    processMsg();

    if (condition) {
        rabbitListenerEndpointRegistry.stop();
        doTask();
        rabbitListenerEndpointRegistry.start();
    }
}
不幸的是,如果我在sink方法中停止侦听器,事务将失败,消息将返回队列。我正在寻找一种在事务完成且侦听器不保存任何消息后调用方法的方法

  • 接收消息并处理消息

  • 完成事务并释放msg如果条件满足,您可以启动一个新线程,该线程将停止侦听器并执行一些任务并启动侦听器。虽然不能保证新线程会在原始侦听器使用任何新消息之前停止侦听器,但它可以大致正常工作

    与手动启动线程不同,您可以拥有一个新队列,在该队列中可以发布消息(如start/stop),并且新侦听器可以在将指令消息放入新队列(如start或stop)时停止原始侦听器

    第二种方法:


    您可以尝试另一种方法,我认为它应该可以工作,而不是将侦听器setMaxConcurrentConsumers停止为0,这应该禁用侦听器,不允许它在不停止侦听器的情况下使用更多消息。完成任务后,将其更改为原始值,我猜在您的情况下为1。

    如果条件满足,您可以启动一个新线程,该线程将停止侦听器并执行一些任务并启动侦听器。虽然不能保证新线程会在原始侦听器使用任何新消息之前停止侦听器,但它可以大致正常工作

    与手动启动线程不同,您可以拥有一个新队列,在该队列中可以发布消息(如start/stop),并且新侦听器可以在将指令消息放入新队列(如start或stop)时停止原始侦听器

    第二种方法:


    您可以尝试另一种方法,我认为它应该可以工作,而不是将侦听器setMaxConcurrentConsumers停止为0,这应该禁用侦听器,不允许它在不停止侦听器的情况下使用更多消息。在完成任务后,将其更改为原始值,我猜在您的情况下为1。

    消息侦听器容器似乎不是适合您的应用程序的方法;你需要一个“拉动”模型

    您可以在上使用
    rabbitmplate.receive()
    receiveAndConvert()
    方法按需提取消息


    如果您在交易之外使用它们,消息将立即得到确认;如果您希望在流程完成后确认消息,请在事务中运行它。

    消息侦听器容器似乎不是应用程序的正确方法;你需要一个“拉动”模型

    您可以在上使用
    rabbitmplate.receive()
    receiveAndConvert()
    方法按需提取消息


    如果您在交易之外使用它们,消息将立即得到确认;如果希望在流程完成后确认消息,请在事务中运行它。

    停止和启动容器的目的是什么?如果容器并发度为1,则在侦听器退出之前,您将不会收到任何新消息。@GaryRussell释放消息后要运行的任务将运行很长时间,在此期间,我不想保留或接收任何新消息。如果将预回迁设置为1,您将不会“保留或接收”任何新消息;但也许您根本不应该使用侦听器容器-请参阅我的答案。@GaryRussell Prefetch不会有帮助,因为我想完成事务->停止侦听器->运行任务->启动侦听器。我无法在事务结束时停止侦听器,因为消息将返回到队列,这将给我带来其他问题。我已经看到了你的答案,但我更愿意在对听众做出任何重大改变之前找到一个解决办法。你只是在为手头的任务使用错误的技术——你把事情复杂化了。我再也帮不上忙了。停下来启动集装箱的目的是什么?如果容器并发度为1,则在侦听器退出之前,您将不会收到任何新消息。@GaryRussell释放消息后要运行的任务将运行很长时间,在此期间,我不想保留或接收任何新消息。如果将预回迁设置为1,您将不会“保留或接收”任何新消息;但也许您根本不应该使用侦听器容器-请参阅我的答案。@GaryRussell Prefetch不会有帮助,因为我想完成事务->停止侦听器->运行任务->启动侦听器。我无法在事务结束时停止侦听器,因为消息将返回到队列,这将给我带来其他问题。我已经看到了你的答案,但我更愿意在对听众做出任何重大改变之前找到一个解决办法。你只是在为手头的任务使用错误的技术——你把事情复杂化了。我再也帮不上忙了。