RabbitMQ的ack机制

1、什么是消息确认ACK。

  答:如果在处理消息的过程中,消费者的服务器在处理消息的时候出现异常,那么可能这条正在处理的消息就没有完成消息消费,数据就会丢失。为了确保数据不会丢失,RabbitMQ支持消息确定-ACK。

2、RabbitMQ的ACK的消息确认机制。

1、ACK机制是消费者从RabbitMQ收到消息并处理完成后,反馈给RabbitMQ,MQ收到反馈后才将此消息从队列中删除。消息的ACK确认机制默认是打开的

2、如果一个消费者在处理消息出现了网络不稳、服务器异常等现象,那么就不会有ACK反馈,RabbitMQ会认为这个消息没有正常消费,会将消息重新放入队列。
3、如果在集群的情况下,RabbitMQ会立即将这个消息推送给这个在线的其他消费者。这种机制保证了在消费者服务端故障的时候,不丢失任何消息和任务。
4、消息永远不会从RabbitMQ中删除,只有当消费者正确发送ACK反馈,RabbitMQ确认收到后,消息才会从RabbitMQ服务器的数据中删除。

3、ACK机制的开发注意事项?

  如果消费者发生异常,ack没法送消息应答。,Message会一直重新分发。然后RabbitMQ会占用越来越多的内容,由于RabbitMQ会长时间运行,因此这个"内存泄漏"是致命的。

4.怎么解决ack的内存泄漏问题?

 1、在程序处理中可以进行异常捕获,保证消费者的程序正常执行。

 2、使用RabbitMQ的ack的配置确认机制。(开启重试次数)

 3、手动设置消息应答。如果消费端异常,也返回应答成功,再把未消费成功的数据记录下来,进行补偿。

# 开启重试
32 spring.rabbitmq.listener.simple.retry.enabled=true
33 # 重试次数,默认为3次
34 spring.rabbitmq.listener.simple.retry.max-attempts=5

 

//第二个参数值为false代表关闭RabbitMQ的自动应答机制,改为手动应答。
channel.basicConsume(QUEUE_NAME, false, consumer);

//在处理完消息时,返回应答状态。
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);

5、消费端的手工ACK与NACK?

1、当我们设置 autoACK=false 时,就可以使用手工ACK方式了,那么其实手工方式包括了手工ACK与NACK。
2、当我们手工 ACK 时,会发送给Broker一个应答,代表消息成功处理了,Broker就可以回送响应给生产端了。NACK 则表示消息处理失败了,如果设置重回队列,Broker端就会将没有成功处理的消息重新发送。
 
消费端进行消费的时候,如果由于业务异常我们可以手工 NACK 并进行日志的记录,然后进行补偿!:

使用方法:void basicNack(long deliveryTag, boolean multiple, boolean requeue):
1、参数:requeue为true,表示deliveryTag=n之前未确认的消息都处理失败且将这些消息重新放回队列中。
2、参数:requeue为false,表示deliveryTag=n之前未确认的消息都处理失败且将这些消息直接丢弃。

3、如果由于服务器宕机等严重问题,那我们就需要手工进行 ACK 保障消费端消费成功!方法:void basicAck(long deliveryTag, boolean multiple)

 

posted @ 2020-03-21 13:18  威兰达  阅读(3538)  评论(0编辑  收藏  举报