在訊息傳遞過程中,如果出現傳遞失敗的情況,傳送會執行重試,重試可能會產生重複的訊息。對系統來說,如果沒有對重複消費進行處理,會導致系統資料發生錯誤。
比如,一個訂單系統,訂單建立成功後,把資料寫入統計資料庫,如果發生重複統計,會導致資料庫資料錯誤。
解決訊息重複消費,其實就是保證訊息的消費冪等性。
冪等性的定義:
多次執行所產生的影響均與一次執行的影響相同。
所以需要從業務邏輯上設計,將消費的業務邏輯設計成冪等性。
利用資料庫的唯一約束
在進行訊息消費,需要取一個唯一個標識,比如 id 作為唯一約束欄位,先新增資料,如果新增失敗,後續做錯誤提示,或者不做後續操作。
Redis 設定全域性唯一id
每次生產者傳送訊息前設定一個全域性唯一id放在訊息體重,並存放的 redis 裡,在消費端介面上先找在redis 檢視是否存在全域性id,如果存在,呼叫消費介面並刪除全域性id,如果不存在,不做後續操作。
多版本(樂觀鎖)機制
給業務資料新增一個版本號,每次更新資料前,比如當前版本和訊息中的版本是否一致,如果一致就更新資料並且版本號+1,如果不一致就不跟新。這有點類似樂觀鎖處理機制。
總結
設計冪等需要根據具體的業務場景,如果是併發量比較大的系統,資料庫一般支撐不了這麼大的併發,需要使用 Redis 快取處理。而併發不大的系統可以選擇資料庫。
如果覺得文章對你有幫助的話,請點個推薦吧!