消息隊列如何處理重復消息


一、消息重復現象

  在 MQTT 協議中,給出了三種傳遞消息時能夠提供的服務質量標准:

      At most once:最多一次,這種情況會丟失部分數據,一般日志收集這種對數據不嚴格的可以使用

      At least once:最少一次,這種會導致一條消息重復發送

  Exactly once:正好一次,一條消息只會被消費一次

      

  RocketMQ,Rabbit MQ,Kafka都是使用的At least once,雖然消息會重復,但不會丟失。不使用Exactly once這種呢,是因為這種每次發送前發送都要檢查這條消息是否已成功發送了,大大降低了MQ的性能。

     

二、解決方案

  那消息重復了,該如何解決呢?一般都是在消費端保證冪等性來解決。

  冪等:f(f(x))=f(x),執行多次和執行一次的結果是相同的,這種我們稱之為冪等的。

  比如現在有個需求:給賬戶A的余額增加100。

  方案一:通過唯一約束控制

    1.數據庫唯一索引:

      流水表中交易訂單號和賬戶建立唯一索引,重復insert的時候違反唯一性,所以只會成功執行一次。

    2.redis的setnx

      redis中有這個key就不能重復操作

  方案二:設置前提條件

    1.數據庫查詢

      加分布式鎖,然后查詢有沒有該訂單號的流水,沒有則可以插入。

    2.數據庫版本號

      查詢出當前記錄以及其中的版本號,更新的時候根據版本號來更新。      

  方案三:全局id

    生產者給數據增加一個全局id,消費端去查詢這個id有沒有消費過,沒有則進行處理。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM