首先咱们要把它的消息确认机制给它关掉:false,当咱们这个消息即使被消费了,在我们的队列中,这个消息标记的同样是未消费的。
紧接着第二点,我们还要做的就是告诉消息队列,在执行消息的时候,不能一次性的把这些消息都给我们的当前的消费者。我们要让消费者在消费消息的时候,当前的一个通道里面只能消费一个消息。
所以这里面我们的代码还要发生一次变化,就是这个变化是什么:当前的通道每一次只能消费一个消息,注意不能说一次性的。因为如果咱们一次性的都发给这个通道的话,它在通道里面放着,它慢慢的去执行,当它执行到第三个宕机的话,后边两个是不是就丢了,所以咱们希望通道每次就一个,没有过来的消息还在队列中保存。所以这里面我们要每次只能消费一个消息:channer.basicQos(1)
public class Consumer1 {
public static void main(String[] args) throws IOException {
Connection connection = RabbitMQUtils.getConnection();
Channel channel = connection.createChannel();
// 通道绑定对应的消息队列: 消费者和生产者在这个方法里面的参数一定要一致
// 参数1 queue: 消息队列的名称,如果该队列不存在,会自动创建; 参数2durable:是否持久化队列
// 参数3 exclusive: 是否独占队列 参数4 autoDelete:消费者消费完成后,是否删除队列
channel.basicQos(1);
channel.queueDeclare("work",true,false,false,null);
// 消费消息
//参数1 queue:消费哪个队列
//参数2 autoAck:开始消息的自动确认机制
//参数3:消费消息时的回调接口
channel.basicConsume("work",false,new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException
{
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("消费者1"+new String(body));
}
});
}
}
public class Consumer2 {
public static void main(String[] args) throws IOException {
Connection connection = RabbitMQUtils.getConnection();
Channel channel = connection.createChannel();
// 通道绑定对应的消息队列: 消费者和生产者在这个方法里面的参数一定要一致
// 参数1 queue: 消息队列的名称,如果该队列不存在,会自动创建; 参数2durable:是否持久化队列
// 参数3 exclusive: 是否独占队列 参数4 autoDelete:消费者消费完成后,是否删除队列
channel.basicQos(1);
channel.queueDeclare("work",true,false,false,null);
// 消费消息
//参数1 queue:消费哪个队列
//参数2 autoAck:开始消息的自动确认机制
//参数3:消费消息时的回调接口
channel.basicConsume("work",false,new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException
{
System.out.println("消费者2"+new String(body));
channel.basicAck(envelope.getDeliveryTag(),false);
}
});
}
}