關於MQ的幾件小事(三)如何保證消息不重複消費

1.冪等性

冪等(idempotent、idempotence)是一個數學與計算機學概念,常見於抽象代數中。 在編程中一個冪等操做的特色是其任意屢次執行所產生的影響均與一次執行的影響相同。冪等函數,或冪等方法,是指可使用相同參數重複執行,並能得到相同結果的函數。這些函數不會影響系統狀態,也不用擔憂重複執行會對系統形成改變。例如,「setTrue()」函數就是一個冪等函數,不管屢次執行,其結果都是同樣的.更復雜的操做冪等保證是利用惟一交易號(流水號)實現.redis

簡單來講,冪等性就是一個數據或者一個請求,給你重複來了屢次,你得確保對應的數據是不會改變的,不能出錯。數據庫

2.出現重複消費場景

(1)首先,好比rabbitmq、rocketmq、kafka,都有可能會出現消息重複消費的問題。由於這個問題一般不是由mq來保證的,而是消費方本身來保證的。
(2)舉例kafka來講明重複消費問題 kafka有一個叫作offset的概念,就是每一個消息寫進去,都有一個offset表明他的序號,而後consumer消費了數據以後,每隔一段時間,會把本身消費過的消息的offset提交一下,表明我已經消費過了,下次就算重啓,kafka就會讓消費者從上次消費到的offset來繼續消費。編程

可是萬事總有例外,若是consumer消費了數據,還沒來得及發送本身已經消費的消息的offset就掛了,那麼重啓以後就會收到重複的數據。 ide

kafka重複消費示意圖.png

3.保證冪等性(重複消費)

要保證消息的冪等性,這個要結合業務的類型來進行處理。下面提供幾個思路供參考:函數

(1)、可在內存中維護一個set,只要從消息隊列裏面獲取到一個消息,先查詢這個消息在不在set裏面,若是在表示已消費過,直接丟棄;若是不在,則在消費後將其加入set當中。post

(2)、如何要寫數據庫,能夠拿惟一鍵先去數據庫查詢一下,若是不存在在寫,若是存在直接更新或者丟棄消息。cdn

(3)、若是是寫redis那沒有問題,每次都是set,自然的冪等性。blog

(4)、讓生產者發送消息時,每條消息加一個全局的惟一id,而後消費時,將該id保存到redis裏面。消費時先去redis裏面查一下有麼有,沒有再消費。rabbitmq

(5)、數據庫操做能夠設置惟一鍵,防止重複數據的插入,這樣插入只會報錯而不會插入重複數據。隊列

上一篇《如何保證消息隊列的高可用
下一篇《如何防止數據隊列數據丟失

相關文章
相關標籤/搜索