rabbitmq 怎么保證冪等性,數據一致性問題


mq的作用主要是用來解耦,削峰,異步,

增加MQ,系統的復雜性也會增加很多,

也會帶來其他的問題,比如MQ掛了怎么辦,怎么保持數據的冪等性

冪等性問題通俗點講就是保證數據不被重復消費,同時數據也不能少,

也就是數據一致性問題。

下面是MQ丟失的3種情況
在這里插入圖片描述

1,生產者發送消息至MQ的數據丟失

解決方法:在生產者端開啟comfirm 確認模式,你每次寫的消息都會分配一個唯一的 id,

然后如果寫入了 RabbitMQ 中,RabbitMQ 會給你回傳一個 ack 消息,告訴你說這個消息 ok 了

2,MQ收到消息,暫存內存中,還沒消費,自己掛掉,數據會都丟失

解決方式:MQ設置為持久化。將內存數據持久化到磁盤中

3,消費者剛拿到消息,還沒處理,掛掉了,MQ又以為消費者處理完

解決方式:用 RabbitMQ 提供的 ack 機制,簡單來說,就是你必須關閉 RabbitMQ 的自動 ack,可以通過一個 api 來調用就行,然后每次你自己代碼里確保處理完的時候,再在程序里 ack 一把。這樣的話,如果你還沒處理完,不就沒有 ack 了?那 RabbitMQ 就認為你還沒處理完,這個時候 RabbitMQ 會把這個消費分配給別的 consumer 去處理,消息是不會丟的。

在這里插入圖片描述

數據重復的問題簡單的多,就是在消費端判斷數據是否已經被消費過

比如你拿個數據要寫庫,你先根據主鍵查一下,如果這數據都有了,你就別插入了,update 一下好吧。
比如你是寫 Redis,那沒問題了,反正每次都是 set,天然冪等性。
比如你不是上面兩個場景,那做的稍微復雜一點,你需要讓生產者發送每條數據的時候,里面加一個全局唯一的 id,類似訂單 id 之類的東西,然后你這里消費到了之后,先根據這個 id 去比如 Redis 里查一下,之前消費過嗎?如果沒有消費過,你就處理,然后這個 id 寫 Redis。如果消費過了,那你就別處理了,保證別重復處理相同的消息即可。
比如基於數據庫的唯一鍵來保證重復數據不會重復插入多條。因為有唯一鍵約束了,重復數據插入只會報錯,不會導致數據庫中出現臟數據。


免責聲明!

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



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