Spring Boot 整合 RabbitMQ,消息重複消費怎麼辦?
- 2020 年 3 月 6 日
- 筆記
今日乾貨

剛剛發表
查看:66666回復:666
公眾號後台回復 SpringBoot,免費獲取 274 頁SpringBoot修鍊手冊。
昨天跟小夥伴們分享了如何在 RabbitMQ 中確保消息發送可靠性的問題(我是如何在微人事項目中提高RabbitMQ消息可靠性的?),我們主要是兩個思路:
- 開啟消息發送失敗回調,路由失敗回調
- 開啟定時任務巡查,發現有發送失敗的消息自動重新投遞
雙管齊下,我們確保了消息發送的可靠性。
但是,在這樣的機制下,又帶來了新的問題,就是消息可能會重複投遞,進而導致,消息重複消費,例如一個員工入職了,結果收到了兩封入職歡迎郵件,這是不對的,所以,今天松哥又給大家帶來了一個新的影片,聊一聊如何確保一條消息只消費一次。
說到這個話題,我們就不得不先來說說消息冪等性。
1.簡單說說冪等性
冪等性本身是數學上的概念,即使公式:f(x)=f(f(x)) 能夠成立的數學性質。在開發領域,則表示對於同一個系統,使用相同的條件,一次請求和多次請求對系統資源的影響是一致的。
在分散式系統中冪等性尤為重要,因為分散式系統中,我們經常會用到介面調用失敗進而進行重試這個功能,這樣就帶來了對一個介面可能會使用相同的條件進行重複調用,在這樣的條件下,保證介面的冪等性就尤為重要了。
了解了問題,那麼解決方案就很好整了,常見的方案有:
- MVCC
- Token 機制
- 設計去重表
- …
MVCC 是多版本並發控制,這種方式就是在數據更新的時候需要去比較所持有的數據版本號,版本號不一致的話,操作會失敗,這樣每個 version 就只有一次執行成功的機會,一旦失敗了必須重新獲取。這種方式松哥以後可以抽空和大家細聊。
Token 則是目前使用比較廣的一種方式,核心思想就是每個操作都有一個唯一憑證 token,一旦執行成功,對於重複的請求,總是返回同一個結果。
2.微人事解決方案
松哥這次在微人事的 RabbitMQ 消費端實際上就是採用了 Token 這種方式。
大致的思路是這樣,首先將 RabbitMQ 的消息自動確認機制改為手動確認,然後每當有一條消息消費成功了,就把該消息的唯一 ID 記錄在 Redis 上,然後每次收到消息時,都先去 Redis 上查看是否有該消息的 ID,如果有,表示該消息已經消費過了,不再處理,否則再去處理。
那麼具體是怎麼實現的呢,請看大螢幕:
好了,通過昨天和今天一共三個影片,松哥主要和大家分享了微人事中是如何解決 RabbitMQ 消息可靠性的,如果小夥伴們沒看昨天的影片,不妨去瞅一瞅:我是如何在微人事項目中提高RabbitMQ消息可靠性的?
當然,如果小夥伴們對完整的微人事項目影片感興趣,可以看看這篇文章【微人事影片教程】。
本文影片中涉及到的所有程式碼包括資料庫腳本,都已經提交到 GitHub 和 Gitee 上了,地址分別是:https://github.com/lenve/vhr 和 https://gitee.com/lenve/vhr ,小夥伴們可以下載參考。