一、RabbitMQ的****消息确认机制
RabbitMQ 提供了两种消息确认机制(Ack Mode):自动确认(auto-ack)和手动确认(manual ack)。
1.自动确认模式:
- 一旦消息被发送到消费者,RabbitMQ 认为这条消息已经被成功消费,会立即从内存中移除该消息。如果消费者在处理过程中崩溃或断开连接,那么这些消息将丢失。
- 在自动确认模式下,RabbitMQ 通常不会等待当前消息被处理完毕再发送下一条消息给同一个消费者。
2.手动确认模式:
- 消费者需要告诉 RabbitMQ 某条消息已经被成功处理,这样 RabbitMQ 才会将其从内存中移除。如果消费者没有发送确认信号,RabbitMQ 会保留该消息,直到收到确认或者发生特定的超时情况。
- 在手动确认模式下,RabbitMQ 会等待当前消息被处理完毕再发送下一条消息给同一个消费者。
二、使用@RabbitListener时的消息确认模式
在使用@RabbitListener监听消息时,通过设置ackMode属性即可设置消费者的消息确认模式。
ackMode有三个可选值:NONE、MANUAL、AUTO,来源于枚举AcknowledgeMode。
- ackMode ="NONE",此时为自动确认模式。
- ackMode ="MANUAL",此时为手动确认模式,需要人为调用channel.basicAck方法表示确认消息,调用channel.basicNack或channel.basicReject方法表示消息未被确认。
- ackMode ="AUTO",此时为手动确认模式,由spring-rabbit依据消息处理中是否抛出异常,从而自动发送ack(无异常)或nack(异常)到rabbitmq。
- 当不指定ackMode时,效果同ackMode="AUTO"。
@RabbitListener(queues = "testQueue", ackMode = "MANUAL")
@RabbitHandler
public void process(Map input, Channel channel, Message message){
long deliveryTag = message.getMessageProperties().getDeliveryTag();
try {
log.info("重试中");
int a = 1/0;
//手动ack 第二个参数为false表示仅确认当前消息,为true表示确认之前所有的消息
channel.basicAck(deliveryTag, false);
}catch (Exception e) {
//手动nack 告诉rabbitmq该消息消费失败 第三个参数:如果被拒绝的消息应该被重新请求,而不是被丢弃或变成死信,则为true
try {
channel.basicNack(deliveryTag, false, true);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
版权归原作者 Increment28 所有, 如有侵权,请联系我们删除。