如何保證消息消費的冪等性


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

冪等性:就是用戶對於同一操作發起的一次請求或者多次請求的結果是一致的,不會因爲多次點擊而產生了副作用。舉個最簡單的例子,那就是支付,用戶購買商品使用約支付,支付扣款成功,但是返回結果的時候網絡異常,此時錢已經扣了,用戶再次點擊按鈕,此時會進行第二次扣款,返回結果成功,用戶查詢餘額返發現多扣錢了,流水記錄也變成了兩條...


業界主流的冪等性操作:

唯一ID + 指紋碼機制,利用數據庫主鍵去重

SELECT COUNT(1) FROM T_ORDER WHERE ID = 唯一ID +指紋碼
好處:實現簡單
壞處:高併發下有數據庫寫入的性能瓶頸
解決方案:跟進ID進行分庫分表進行算法路由


使用Redis的原子特性去重

使用Redis進行冪等,需要考慮的問題
第一:我們是否要進行數據落庫,如果落庫的話,關鍵解決的問題是數據庫和緩存如何做到原子性?
第二:如果不進行落庫,那麼都存儲到緩存中,如何設置定時同步的策略?


常見解決思路

  • 比如你拿個數據要寫庫,你先根據主鍵查一下,如果這數據都有了,你就別插入了,update 一下好吧。
  • 比如你是寫 Redis,那沒問題了,反正每次都是 set,天然冪等性。
  • 比如你不是上面兩個場景,那做的稍微複雜一點,你需要讓生產者發送每條數據的時候,裏面加一個全局唯一的 id,類似訂單 id 之類的東西,然後你這裏消費到了之後,先根據這個 id 去比如 Redis 裏查一下,之前消費過嗎?如果沒有消費過,你就處理,然後這個 id 寫 Redis。如果消費過了,那你就別處理了,保證別重複處理相同的消息即可。
  • 比如基於數據庫的唯一鍵來保證重複數據不會重複插入多條。因爲有唯一鍵約束了,重複數據插入只會報錯,不會導致數據庫中出現髒數據。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章