前言:消息中間件 是用來 客戶端 與 客戶端之間通信的羔杨,那么就存在以下兩個(gè)問題:
- 如何避免消息重復(fù)消費(fèi)(針對consumer)
- 如何保證消息的可靠性投遞(針對publisher)
問題2看《消息100%投遞的2種方案》
這一文講問題1:如何避免消息重復(fù)消費(fèi)
上圖是消息投遞的整個(gè)流程娜庇,熟悉該流程有助于理解本文
先理解 冪等性 這個(gè)概念,有助于后續(xù)理解 如何避免消息重復(fù)消費(fèi)
冪等性:
在編程上栖袋,指任意多次執(zhí)行所產(chǎn)生的影響均與一次執(zhí)行的影響相同。
在數(shù)學(xué)上,指冪等方法吟榴,是可以使用相同的參數(shù)重復(fù)執(zhí)行,并獲得相同結(jié)果的函數(shù)囊扳。不用擔(dān)心重復(fù)執(zhí)行會對系統(tǒng)造成改變吩翻。
避免消息重復(fù)問題上,就是要實(shí)現(xiàn)類似 冪等方法 的功能锥咸,使消費(fèi)者即使多次消費(fèi)了同樣的信息狭瞎,結(jié)果也只跟消費(fèi)了1次消息的結(jié)果一樣,不會對業(yè)務(wù)造成影響搏予。
下面用一個(gè)實(shí)際場景來舉例冪等性的實(shí)現(xiàn):
場景1:秒殺活動(如雙十一脚作,春節(jié)高鐵買票)
用count表示庫存
比如庫存100,賣一件庫存減1,減到0就不能再減球涛,sql如下
update 表名 set count = count -1
但如果庫存只剩1劣针,這時(shí)候剛好有2個(gè)請求同時(shí)上來,這時(shí)候再去減庫存亿扁,
庫存可能變?yōu)?1捺典,這就出現(xiàn)了超賣行為,在業(yè)務(wù)上是不允許的从祝,如何解決襟己?
可以通過加1個(gè)版本號(version)來解決
原先的步驟是直接減庫存,加 version 后牍陌,改成 先查詢 version 號擎浴,再執(zhí)行減庫存操作,sql如下:
update 表名 set count = count -1 , version = version + 1 where version = 1
這樣當(dāng)并發(fā)請求發(fā)送來時(shí)毒涧,由于版本號被更新贮预,后續(xù)的版本號找不到,
就不會執(zhí)行減庫存操作契讲,用加 version 的方法來實(shí)現(xiàn)類似樂觀鎖的效果