消息隊列的冪等性
在前面的文章中已經說到,消息隊列是通過超時-重發-確認機制來保證其可靠性(消息必答)。但由於採用了重發機制,可能導致同一條消息多次消費,MQ還需要保證冪等性。
MQ的冪等性包括發送消息和接受消息兩個部分。
一、發送消息的冪等性
- 發送端MQ-client把消息發送給服務端MQ-server
- 服務端MQ-server將消息落地
- 服務端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:消息隊列 |