上一篇讲解了如何使用Java实现一个work队列模式,并实现能做多劳的效果。本篇我们来了解一下有关RabbitMQ的“消息的确认模式”。
当消费者从队列中获取消息后,服务端是如何知道自己被消费的呢?在RabbitMQ中服务端确认消息是否被消费成功,有两种确认模式:
(1)自动确认
只要消息从队列中获取,无论消费者获取到消息后是否有成功接收的反馈,都认为是消息已经被成功消费。
(2)手动模式
消费者从队列中获取消息后,服务器会将消息标记为不可用状态,等待消费者的反馈,如果消费者一直没有反馈,那么消息将一直处于不可用状态。
那么,以上两种模式的应用场景是什么呢?这就要看实际开发中的需求情况来定。
例如,我们在之前编写的“HelloWorld”简单队列模式的样例中,我们获取消息的代码为:
//获取消息 while(true){ QueueingConsumer.Delivery delivery = consumer.nextDelivery(); String message = new String(delivery.getBody()); System.out.println("[Consumer] Received '"+ message +"'"); }
此时可以看到,我们在消费者从队列中获取数据后,没有做其他处理,说明这种模式是自动确认模式。
而在上一篇我们讲解work队列模式时,编写的消费者获取信息代码如下:
// 获取消息 int Count = 0;// 统计收到的信息历史条数 while (true) { QueueingConsumer.Delivery delivery = consumer.nextDelivery(); String message = new String(delivery.getBody()); System.out.println(" [consumer1] Received '" + message + "'"); System.out.println(" now Received MessageSize:'" + ++Count + "'"); //休眠10ms Thread.sleep(10); // 返回确认状态 channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
这里的“channel.basicAck...”就是给服务器一个反馈,告知服务器已经成功消费,这里是属于“手动模式”。
“手动模式”与“自动模式”的区别就是,当我们创建消费者对象并且设置消费者对队列进行监听时,设置的第二个参数的不同,对于自动模式:
//定义队列的消费者 QueueingConsumer consumer = new QueueingConsumer(channel); //监听队列 channel.basicConsume(QUEUE_NAME, true,consumer);
对于手动模式:
// 定义队列的消费者 QueueingConsumer consumer = new QueueingConsumer(channel); // 监听队列,手动返回完成 channel.basicConsume(QUEUE_NAME, false, consumer);
上面的两段代码中,basicConsume方法的三个参数分别代表:队列名称、是否自动确认(否将需要手动确认)、接收消息的消费者对象。
所以在定义消费者监听队列时,设置basicConsume方法的第二个参数为true,则使用的是自动模式,下面消费者接收完信息后无需确认。而当第二个参数为false时,下面的消费者接收完信息后需要进行手动编码确认(channel.basicAck...)。
原文链接:https://blog.csdn.net/acmman/article/details/79506535