前言:上篇文章说了发送端消息确认机制,该篇介绍消费端消息确认机制。
消费端确认(在确保每个消息被正确消费的情况,此时才可以将broker 删除这个消息)
消费端消息机制默认是自动确认的,只要消息接收到,客户端会自动确认,服务端就会移除这个消息,但是该情况下存在问题:
- 当服务器突然宕机的情况下,此时的消费者接收到消息,但是并没有签收确认,这个时候这条消息就会丢失
所以我们这时候可以将自动消费设置成手动签收消息
spring:
rabbitmq:
listener:
simple:
acknowledge-mode: manual
acknowledge-mode: none 自动模式(默认开启)
acknowledge-mode: manual 手动模式
acknowledge-mode: auto 自动模式 (根据侦听器检测是正常返回、还是抛出异常来发出 ack/nack)
手动模式可以确保我们在没有签收的情况下保证消息的不丢失。即使服务器宕机的情况下,只要没有手动ack,都是unacked状态,这时候会将这条消息重新放回队列,变成ready状态。
@RabbitHandler
public void receiveMessage(Message message,MessageUtil messageUtil, Channel channel){
//channel内按顺序自增
long deliveryTag = message.getMessageProperties().getDeliveryTag();
try {
/**
* 签收货物 false为非批量签收
*
*/
channel.basicAck(deliveryTag,false);
} catch (IOException e) {
System.out.println(e);
}
System.out.println("接受到的消息为:"+messageUtil);
}
我们打开RabbitMQ的channel源码,basicAck两个参数分别为:
void basicAck(long deliveryTag, boolean multiple) throws IOException;
我们可以手动退货,相关参数
* 1. channel内顺序自增ID
* 2. multiple false为不是批量退货
* 3. requeue 为是否返回队列 true 返回 ,false 丢弃
代码示例为:
/**
* 退货
* 1. channel内顺序自增ID
* 2. multiple false为不是批量退货
* 3. requeue 为是否返回队列 true 返回 ,false 丢弃
*/
channel.basicNack(deliveryTag,false,true);
好了,消息确认机制就写到这了。