Spring boot 如何使用@RabbitListener停止和重新启动来自RabbitMQ的消息

Spring boot 如何使用@RabbitListener停止和重新启动来自RabbitMQ的消息,spring-boot,spring-rabbit,Spring Boot,Spring Rabbit,我能够停止消费并重新启动消费,但问题是,当我重新启动消费时,我能够处理已发布的消息,但当我发布无法处理的新消息时 import com.rabbitmq.client.Channel; import com.rabbitmq.client.Consumer; @Component public class RabbitMqueue implements Consumer { int count = 0; @RabbitListener(queues="dataQueue") public

我能够停止消费并重新启动消费,但问题是,当我重新启动消费时,我能够处理已发布的消息,但当我发布无法处理的新消息时

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Consumer;

@Component
public class RabbitMqueue implements Consumer {

int count = 0;

@RabbitListener(queues="dataQueue")
public void receivedData(@Payload Event msg, Channel channel, 
          @Header(AmqpHeaders.CONSUMER_TAG) String tag) throws IOException, 
                InterruptedException {

count++;
System.out.println("\n Message recieved from the Dataqueue is " + msg);

//Canceling consuming working fine.
if(count == 1) {
    channel.basicCancel(tag);
    System.out.println("Consumer is cancle");
}

count++;
System.out.println("\n count is " + count + "\n");

Thread.sleep(5000);

//restarting consumer. able to process already consumed messages
//but not able to see the newly published messages to the queue I mean
//newly published message is moving from ready to unack state but nothing 
//happening on the consumer side. 

if(count == 2) {
    channel.basicConsume("dataQueue", this);
            System.out.println("Consumer is started "); 
    }       
  }
}

您不能这样做
channel.basicCancel(标记)

渠道/消费者由Spring管理;对于consumer参数,您应该做的唯一一件事是ack或nack消息(即使很少需要,也最好让容器来做ack)

要停止/启动使用者,请使用端点注册表

为注释创建的容器未在应用程序上下文中注册。通过调用
RabbitListenerEndpointRegistry
bean上的
getListenerContainers()
,可以获得所有容器的集合。然后,您可以迭代此集合,例如,停止/启动所有容器,或调用注册表本身上的
生命周期
方法,该方法将调用每个容器上的操作

e、 g.
registry.stop()
将停止所有侦听器

您还可以使用单个容器的id,使用
getListenerContainer(String id)
,获取对单个容器的引用;例如,
registry.getListenerContainer(“multi”)
,用于上面代码段创建的容器


如果您使用的是AMQP/Rabbit,您可以尝试以下方法之一:

1) 在代码中防止启动时启动:

@Bean
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(ConnectionFactory connectionFactory) {
    SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
    factory.setConnectionFactory(connectionFactory);

    //
    //autoStartup = false, prevents handling messages immedeatly. You need to start each listener itselve. 
    //
    factory.setAutoStartup(false); 

    factory.setMessageConverter(new Jackson2JsonMessageConverter());
    return factory;
}
2) 在app.yml/props中防止启动时启动:

rabbitmq.listener.auto-startup: false
rabbitmq.listener.simple.auto-startup: false
3) 启动/停止单个侦听器

给@RabbitListener一个id:

@RabbitListener(queues = "myQ", id = "myQ")
...
以及:

@Autowired
private RabbitListenerEndpointRegistry rabbitListenerEndpointRegistry;

MessageListenerContainer listener = 
   rabbitListenerEndpointRegistry.getListenerContainer("myQ");
    ...
listener.start();
...
listener.stop();