1. 程式人生 > >RabbitMQ訊息應答------ack機制

RabbitMQ訊息應答------ack機制

Message acknowledgment(訊息應答)

執行一個任務可能需要花費幾秒鐘,你可能會擔心如果一個消費者在執行任務過程中掛掉了。一旦RabbitMQ將訊息分發給了消費者,就會從記憶體中刪除。在這種情況下,如果正在執行任務的消費者宕機,會丟失正在處理的訊息和分發給這個消費者但尚未處理的訊息。

但是,我們不想丟失任何任務,如果有一個消費者掛掉了,那麼我們應該將分發給它的任務交付給另一個消費者去處理。

為了確保訊息不會丟失,RabbitMQ支援訊息應答。消費者傳送一個訊息應答,告訴RabbitMQ這個訊息已經接收並且處理完畢了。RabbitMQ就可以刪除它了。

如果一個消費者掛掉卻沒有傳送應答,RabbitMQ會理解為這個訊息沒有處理完全,然後交給另一個消費者去重新處理。這樣,你就可以確認即使消費者偶爾掛掉也不會丟失任何訊息了。

沒有任何訊息超時限制;只有當消費者掛掉時,RabbitMQ才會重新投遞。即使處理一條訊息會花費很長的時間。

訊息應答是預設開啟的。我們通過顯示的設定autoAsk=true關閉這種機制現即自動應答開,一旦我們完成任務,消費者會自動傳送應答通知RabbitMQ訊息已被處理,可以從記憶體刪除。如果消費者因宕機或連結失敗等原因沒有傳送ACK(不同於ActiveMQ,在RabbitMQ裡,訊息沒有過期的概念),則RabbitMQ會將訊息重新發送給其他監聽在佇列的下一個消費者。

程式碼示例:

生產者端程式碼不變,消費者端程式碼這部分就是用於開啟手動應答模式的。

// 監聽佇列,手動返回完成
channel.basicConsume(QUEUE_NAME, false, consumer);

注:第二個引數值為false代表關閉RabbitMQ的自動應答機制,改為手動應答。

在處理完訊息時,返回應答狀態。

// 返回確認狀態
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
在處理完訊息時,返回應答狀態。