訊息佇列 重複消費問題

2021-10-13 19:52:29 字數 1019 閱讀 6240

​ 所謂冪等性,就是資料無論操作多少次,所產生的影響跟執行一次是一樣的,比如對於讀操作來說,無論讀取多少次資料,都跟讀取一次的資料是一樣的,所以讀操作是乙個冪等性操作,而新增操作,新增多次會有多條記錄,因而寫操作則是非冪等性操作。因而對於以上場景,只要保證訊息消費的冪等性,就能解決重複消費的問題。

常見的幾種設計冪等的方法:

可以通過給訊息的某一些屬性設定唯一約束,比如增加唯一uuid,新增的時候查詢是否存對應的uuid,存在不操作,不存在則新增,那樣對於相同的uuid只會存在一條資料。其實,只要類似「insert if not exist」的操作都可能,但需要保證查詢跟新增的操作必須是原子性操作。例如:上面取款發簡訊的場景則可以借助redis的setnx實現。

public

class

sendserviceimpl

implements

sendservice

return

true;}

}

在更新的時候,可以通過設定一定的前置條件來保證資料冪等,比如給使用者傳送簡訊是非冪等操作,但可以新增前置條件,變成如果該使用者未傳送過簡訊,則給使用者傳送簡訊,此時的操作則是冪等性操作。但在實際上,對於乙個問題如何獲取前置條件往往比較複雜,此時可以通過設定版本號version,沒修改一次則版本號+1,在更新時則通過判斷兩個資料的版本號是否一致。

update message set m_status = # where uuid = # and version = #
最後的方式就比較暴力也比較通用,通過設定全域性id去實現。實現的思路是,在傳送訊息時,給每條訊息指定乙個全域性唯一的 id(可以通過雪花演算法去實現),消費時,先根據這個 id 檢查這條訊息是否有被消費過,如果沒有消費過,才更新資料。

雖然看起來好像不複雜,單機環境實現也比較簡單,就是查詢更新的思路,但在分布式環境上一點也不簡單,因為必須保證查詢跟更新是原子性的操作,不能查詢完又有另外乙個事務去更新了資料。當然,對於這種問題也可以通過分布式事務和分布式鎖去實現,但與之的也降低了系統的效能。

訊息佇列三 訊息重複消費問題(冪等性)

其實這個很常見的乙個問題,這倆問題基本可以連起來問。既然是消費訊息,那肯定要考慮考慮會不會重複消費?能不能避免重複消費?或者重複消費了也別造成系統異常可以嗎?這個是mq領域的基本問題,其實本質上還是問你使用訊息佇列如何保證冪等性,這個是你架構裡要考慮的乙個問題。要考慮的實際生產上的系統設計問題。首先...

佇列訊息重複消費解決

其實這個很常見的乙個問題,這倆問題基本可以連起來問。既然是消費訊息,那肯定要考慮考慮會不會重複消費?能不能避免重複消費?或者重複消費了也別造成系統異常可以嗎?這個是mq領域的基本問題,其實本質上還是問你使用訊息佇列如何保證冪等性,這個是你架構裡要考慮的乙個問題。要考慮的實際生產上的系統設計問題。首先...

04 如何保證訊息佇列中的訊息不被重複消費

1 面試題 如何保證訊息不被重複消費啊 如何保證訊息消費時的冪等性 2 面試官心裡分析 其實這個很常見的乙個問題,這倆問題基本可以連起來問。既然是消費訊息,那肯定要考慮考慮會不會重複消費?能不能避免重複消費?或者重複消費了也別造成系統異常可以嗎?這個是mq領域的基本問題,其實本質上還是問你使用訊息佇...