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)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM