rabbitmq — 消息確認機制解析

對於某些消息而言,我們有時候需要嚴格的知道消息是否已經被 consumer 監聽消費處理了,即我們有一種消息確認機制來保證我們的消息是否已經真正的被消費處理。在 RabbitMQ 中,消息確認處理機制有三種:Auto - 自動、Manual - 手動、None - 無需確認,而確認機制需要 listener 實現 ChannelAwareMessageListener 接口,並重寫其中的確認消費邏輯。

1. 自動確認

AcknowledgeMode.NONE
RabbitMQ成功將消息發出(即將消息成功寫入TCP Socket)中立即認爲本次投遞已經被正確處理,不管消費者端是否成功處理本次投遞。
所以這種情況如果消費端消費邏輯拋出異常,也就是消費端沒有處理成功這條消息,那麼就相當於丟失了消息。
一般這種情況我們都是使用try catch捕捉異常後,打印日誌用於追蹤數據,這樣找出對應數據再做後續處理。

2.手動確認 

這個比較關鍵,也是我們配置接收消息確認機制時,多數選擇的模式。
消費者收到消息後,手動調用basic.ack/basic.nack/basic.reject後,RabbitMQ收到這些消息後,才認爲本次投遞成功。

  • basic.ack用於肯定確認
  • basic.nack用於否定確認(注意:這是AMQP 0-9-1的RabbitMQ擴展)
  • basic.reject用於否定確認,但與basic.nack相比有一個限制:一次只能拒絕單條消息

消費者端以上的3個方法都表示消息已經被正確投遞,但是basic.ack表示消息已經被正確處理。而basic.nack,basic.reject表示沒有被正確處理:

channel.basicReject(deliveryTag, true)

拒絕消費當前消息,如果第二參數傳入true,就是將數據重新丟回隊列裏,那麼下次還會消費這消息。設置false,就是告訴服務器,我已經知道這條消息數據了,因爲一些原因拒絕它,而且服務器也把這個消息丟掉就行。 下次不想再消費這條消息了。

使用拒絕後重新入列這個確認模式要謹慎,因爲一般都是出現異常的時候,catch異常再拒絕入列,選擇是否重入列。

但是如果使用不當會導致一些每次都被你重入列的消息一直消費-入列-消費-入列這樣循環,會導致消息積壓。

channel.basicNack(deliveryTag, false, true):

第一個參數依然是當前消息到的數據的唯一id;
第二個參數是指是否針對多條消息;如果是true,也就是說一次性針對當前通道的消息的tagID小於當前這條消息的,都拒絕確認。
第三個參數是指是否重新入列,也就是指不確認的消息是否重新丟回到隊列裏面去。

同樣使用不確認後重新入列這個確認模式要謹慎,因爲這裏也可能因爲考慮不周出現消息一直被重新丟回去的情況,導致積壓。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章