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