MQ消息中間件技術精講10 高級篇三 冪等性保障不重複消費
利用冪等性保障消息不被重複消費
本文主要內容:
一:冪等性概念
什麼是冪等性?
在網路超時等問題除外下,要求一次或多次請求同一個資源,對資源本身產生的影響和第一次執行的影響相同。
關於冪等性更詳細的介紹,可以參見《拓展知識一:冪等性》這篇文章。
冪等性我們可以借鑒資料庫的樂觀鎖機制來理解:
比如,我們執行一條更新庫存的sql語句:
update table set count = count -1 where id = 1
流程說明:
在高並發的情況下,比如秒殺系統,現在商品就剩下一個了。如果我們執行:update table set count = count -1 where id = 1這個sql語句的時候,高並發情況會導致庫存成為負數,這種操作是有問題的。所以我們可以就是用樂觀鎖:
添加版本欄位,通過版本號欄位來處理。
在查詢的時候,假設查詢的版本號是1,在更新的時候拿著版本號作為更新條件即where version=1來更新。高並發時候,第一個執行完成後,version 1了。當第二條更新時候,發現已經不是1了就更新不了。關於mysql資料庫樂觀鎖和悲觀鎖的詳細介紹,可以參見《拓展知識二:mysql資料庫中樂觀鎖和悲觀鎖》
二:消費端如何保障冪等性消費
問題:
在海量訂單產生的業務高峰期,如何避免消息被重複的消費呢?
答案:在消費端實現冪等性即可。
消息端實現冪等性,就意味著,我們的消息永遠不會消費多次,即使我們發送多條一樣的消息
三:業界主流的冪等性操作
唯一ID 指紋碼機制
名稱解釋:
唯一ID:如資料庫的主鍵id
指紋碼:業務規則標識唯一的。如時間戳 銀行返回的唯一碼。需要注意的是,這個指紋碼不一定就是我們系統生產的,可能是我們自己業務規則或者是外部返回的一些規則經過拼接後的東西。其目的:就是為了保障此次操作達到絕對唯一的。
唯一ID 指紋碼機制,利用資料庫主鍵去重。如:
Select count(id) from table where id = 唯一ID 指紋碼
好處:實現簡單
壞處:高並發下有資料庫希爾的性能瓶頸
解決方案:對唯一ID進行分庫分表進行演算法路由
利用redis原子特性實現
使用redis進行冪等需要考慮的問題
第一:我們是否需要進行數據入?如果需要入庫的話,關鍵解決的問題是資料庫和緩存如何做到原子性?
第二:如果步進行入庫?那麼都存儲在緩存中,如何設置定時同步的策略?
這兩個問題歡迎大家發表自己的見解。
在下節中,我們將學習Confirm消息確認機制。
TAG:凱哥java |