上一篇讲解了如何使用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

02-12 03:51