標籤:

消息隊列的冪等性

在前面的文章中已經說到,消息隊列是通過超時-重發-確認機制來保證其可靠性(消息必答)。但由於採用了重發機制,可能導致同一條消息多次消費,MQ還需要保證冪等性。

MQ的冪等性包括發送消息和接受消息兩個部分

一、發送消息的冪等性

  1. 發送端MQ-client把消息發送給服務端MQ-server
  2. 服務端MQ-server將消息落地
  3. 服務端MQ-server把ACK發送給MQ-client

如果3丟失,MQ-client發現超時後會重發消息,導致MQ-server會收到多條消息。

如果MQ是冪等的,2不會發生。

怎樣保證冪等性呢?我以為是一個複雜的機制,其實原理很簡單,只需要使用id去重即可。

對每條消息,MQ-server生成一個內部的msg-id,這個msg-id必須是MQ唯一,且與業務無關,對發送方和接收方透明

二、接受消息的冪等性

4. 服務端MQ-server將消息發送給接收端MQ-client

5. 接收端MQ-client發送ACK給服務端

6. MQ-server把消息刪除

需要強調的是,5是業務消費方的操作,不能讓MQ-client擅自處理,因為MQ-client不知道什麼時候消息會被消費成功

如果5丟失,那麼4會重複,MQ-client會接到多個消息。

此時的冪等還是依賴id去重,讓消息中包含一個id,此id也是全局唯一,必須和業務相關,比如訂單ID、帖子ID。

接收方根據此ID做去重,可以保證冪等性。

三、總結

發送消息的冪等性,根據msg-id保證,與業務無關,由MQ生成。。

接受消息的冪等性,根據業務id保證,與業務相關,對MQ透明

2018-01-02閱:

這篇文章有一點似乎有誤。msg-id應該是MQ-client生成的。

參考資料:消息匯流排真的能保證冪等?


推薦閱讀:

消息隊列的使用場景
Kafka基礎概念
Spring 整合JMS 基於ActiveMQ 實現消息的發送接收
螞蟻消息中間件 (MsgBroker) 在 YGC 優化上的探索

TAG:消息隊列 |