前言:消息中間件 是用來 客戶端 與 客戶端之間通信的,那么就存在以下兩個問題:
- 如何避免消息重復消費(針對consumer)
- 如何保證消息的可靠性投遞(針對publisher)
問題2看《消息100%投遞的2種方案》
這一文講問題1:如何避免消息重復消費

上圖是消息投遞的整個流程,熟悉該流程有助于理解本文
先理解 冪等性 這個概念,有助于后續(xù)理解 如何避免消息重復消費
冪等性:
在編程上,指任意多次執(zhí)行所產(chǎn)生的影響均與一次執(zhí)行的影響相同。
在數(shù)學上,指冪等方法,是可以使用相同的參數(shù)重復執(zhí)行,并獲得相同結(jié)果的函數(shù)。不用擔心重復執(zhí)行會對系統(tǒng)造成改變。
避免消息重復問題上,就是要實現(xiàn)類似 冪等方法 的功能,使消費者即使多次消費了同樣的信息,結(jié)果也只跟消費了1次消息的結(jié)果一樣,不會對業(yè)務(wù)造成影響。
下面用一個實際場景來舉例冪等性的實現(xiàn):
場景1:秒殺活動(如雙十一,春節(jié)高鐵買票)
用count表示庫存
比如庫存100,賣一件庫存減1,減到0就不能再減,sql如下
update 表名 set count = count -1
但如果庫存只剩1,這時候剛好有2個請求同時上來,這時候再去減庫存,
庫存可能變?yōu)?1,這就出現(xiàn)了超賣行為,在業(yè)務(wù)上是不允許的,如何解決?
可以通過加1個版本號(version)來解決
原先的步驟是直接減庫存,加 version 后,改成 先查詢 version 號,再執(zhí)行減庫存操作,sql如下:
update 表名 set count = count -1 , version = version + 1 where version = 1
這樣當并發(fā)請求發(fā)送來時,由于版本號被更新,后續(xù)的版本號找不到,
就不會執(zhí)行減庫存操作,用加 version 的方法來實現(xiàn)類似樂觀鎖的效果