RabbitMQ 冪等性概念及業界主流解決方案

一、什麼是冪等性

可以參考數據庫樂觀鎖機制,比如執行一條更新庫存的 SQL 語句,在併發場景,為了性能和數據可靠性,會在更新時加上查詢時的版本,並且更新這個版本信息。可能你要對一個事情進行操作,這個操作可能會執行成百上千次,但是操作結果都是相同的,這就是冪等性。

二、消費端的冪等性保障

在海量訂單生成的業務高峰期,生產端有可能就會重複發生了消息,這時候消費端就要實現冪等性,這就意味著我們的消息永遠不會被消費多次,即使我們收到了一樣的消息。

業界主流的冪等性有兩種操作:

1.唯一 ID + 指紋碼 機制,利用數據庫主鍵去重
2.利用redis的原子性去實現

三、唯一 ID + 指紋碼 機制

大家肯定懂唯一 ID 的,就不多說了,為什麼需要指紋碼呢?這是為了應對用戶在一瞬間的頻繁操作,這個指紋碼可能是我們的一些規則或者時間戳加別的服務給到的唯一信息碼,它並不一定是我們系統生成的,基本都是由我們的業務規則拼接而來,但是一定要保證唯一性,然後就利用查詢語句進行判斷這個id是否存在數據庫中。

好處就是實現簡單,就一個拼接,然後查詢判斷是否重複。

壞處就是在高併發時,如果是單個數據庫就會有寫入性能瓶頸

解決方案 :根據 ID 進行分庫分表,對 id 進行算法路由,落到一個具體的數據庫,然後當這個 id 第二次來又會落到這個數據庫,這時候就像我單庫時的查重一樣了。利用算法路由把單庫的冪等變成多庫的冪等,分攤數據流量壓力,提高性能。

四、利用 redis 的原子性去實現

相信大家都知道 redis 的原子性操作,我這裡就不需要過多介紹了。

使用 redis 的原子性去實現需要考慮兩個點

一是 是否 要進行數據落庫,如果落庫的話,關鍵解決的問題是數據庫和緩存如何做到原子性? 數據庫與緩存進行同步肯定要進行寫操作,到底先寫 redis 還是先寫數據庫,這是個問題,涉及到緩存更新與淘汰的問題

二是如果不落庫,那麼都存儲到緩存中,如何設置定時同步的策略? 不入庫的話,可以使用雙重緩存等策略,保障一個消息副本,具體同步可以使用類似 databus 這種同步工具。

關注我:私信回覆“555”獲取往期Java高級架構資料、源碼、筆記、視頻Dubbo、Redis、Netty、zookeeper、Spring cloud、分佈式、高併發等架構技術往期架構視頻截圖


分享到:


相關文章: