RocketMQ的訊息是怎麼丟失的

王子發表於2020-10-12

 

前言

通過之前文章的閱讀,有關RocketMQ的底層原理相信小夥伴們已經有了一個比較清晰的認識。

那麼接下來王子想跟大家討論一個話題,如果我們的專案中引入了MQ,勢必要面對的一個問題,就是訊息丟失問題,今天我們就來聊聊訊息是怎麼丟失的。

現在假設我們的業務是這樣的,使用者通過訂單系統下了一個訂單,訂單系統完成支付後會傳送訊息給RocketMQ,然後積分系統會從RocketMQ中消費訊息,去給使用者增加積分,如下圖:

 

 

但是突然有一天有使用者反映,支付訂單之後,自己的積分並沒有增長,這是為什麼呢?

經過排查日誌,我們只發現了推送訊息給MQ的日誌,而沒有發現積分系統消費這條訊息的日誌,這就導致了積分系統並沒有給使用者發放積分。

也就是說,訊息在傳輸過程中丟失了。

在系統的核心鏈路中,如果發生訊息丟失的問題,可能會產生惡劣的後果,為了解決此類問題,我們必須弄明白什麼時候會發生訊息丟失。

 

訂單系統推送訊息過程中會丟失訊息嗎?

我們先來看一下整個流程的第一步,訂單系統在支付成功之後,一定會把支付成功的訊息推送給MQ,那麼在這個推送的過程中,訊息可能丟失嗎?

答案是肯定的,一定會存在訊息丟失的情況

比較常見的情況就是網路抖動,在推送訊息這一過程中是通過網路進行通訊的,那麼這個時候如果恰巧網路出現了故障,導致通訊失敗了,那麼這個訊息必然就不會成功的推送到MQ中。

那除了網路抖動外,還有沒有其他的情況導致推送失敗呢?

其實情況有很多,比如MQ成功接收到了訊息,但是MQ本身的網路模組的程式碼出現了異常,可能是內部實現的bug,導致訊息沒有成功處理。

或者當我們推送訊息給一個MQ的主從叢集的時候,剛好遇到Leader節點出現故障,其他的Follower正在嘗試切換為Leader,這個過程中也可能導致訊息丟失。

類似的問題還有其他的。

所以我們首先要明確一點,無論我們使用任何MQ中介軟體的時候,你傳送出的訊息都不一定能成功,而失敗的時候有可能會在你的程式碼裡發生異常,也有可能不會丟擲異常,具體要看什麼情況導致的傳送失敗。

 

MQ接收到訊息後,自己會把訊息弄丟嗎?

接下來假設我們訂單系統推送到MQ這一過程沒有任何問題,訊息成功到達了MQ中,此時訂單系統會認為訊息寫入成功了,那麼這時候訊息就一定不會丟失了嗎?

答案是否定的,這個時候也不能保證訊息的不丟失,我們來分析一下。

通過之前文章的瞭解,相信大家都還記得,當訊息寫入到MQ後,MQ會把訊息先寫入到os cache,也就是作業系統的快取區中,本質也是記憶體,如下圖:

 

也就是說,你認為傳送成功的訊息,可能只存在於記憶體中,還沒到磁碟中。

那麼如果這個時候機器當機了,os cache中的訊息資料將會跟著丟失掉,是不是這個理。

 

那麼現在假設訊息已經重新整理到磁碟上了,是不是就可以保證萬無一失了呢?

顯然這個時候也是不能完全保證的,因為雖然你把資料儲存到了磁碟中,但是如果磁碟發生了故障,資料還是會丟失掉。

如果大家平時有了解一下新聞熱點,會聽說過某某網際網路公司,由於資料儲存在磁碟上沒有冗餘備份,結果磁碟發生故障導致好多年的核心資料全部丟失,大量工作都功虧一簣,這就是血淋淋的教訓。

 

積分系統消費到了訊息就能保證訊息的不丟失了嗎?

那麼到現在,經歷了重重困境,假設積分系統終於能夠消費到這條訊息了,那麼它就能安穩的把積分正常的發放給使用者嗎?

答案依然是否定的。

看過之前文章的小夥伴們應該還記得消費者在進行消費時,是有一個offset的概念的。

這個offset說白了就是個進度標識,讓MQ知道消費者消費到了哪,下次好接著向下消費。

現在假設我們有兩條訊息,offset為1和2。

 

假設我們的積分系統接收到了訊息1,那麼訊息1就在積分系統的記憶體中,正要準備給使用者發放積分。

而預設情況下,消費者會自動提交已經消費的訊息的offset,所以當積分系統獲取訊息後,可能直接就把訊息1的offset提交給了MQ,標識為已經處理了這條訊息。

那麼此時,如果積分系統突然當機,還未發放積分給使用者,那麼這條訊息1自然就丟失了,因為MQ已經把他標記成了已處理,實際積分系統還未處理。

所以消費者獲得訊息後也是可能發生訊息丟失的。

 

總結

好了,看過今天的文章,相信小夥伴們對於RocketMQ的訊息是怎麼丟失的會有一個更深刻的印象。

總結起來就是以下幾點:

1.生產者傳送訊息到MQ這一過程導致訊息丟失

2.MQ自己發生故障導致訊息丟失

3.消費者拿到訊息後,由於操作不當導致訊息丟失

所以任何的技術引入生產環境都是有風險的,引入前我們一定要做好功課。

今天的文章就說到這,小夥伴們可能會問王子,聊了這麼多,到底應該如何解決掉訊息丟失的問題呢?

別急,我們下篇文章就會有解決方案了。

那麼小夥伴們針對MQ的訊息丟失問題是怎麼解決的呢,歡迎大家留言和王子一起討論。

 

往期文章推薦:

什麼是訊息中介軟體?主要作用是什麼?

常見的訊息中介軟體有哪些?你們是怎麼進行技術選型的?

你懂RocketMQ 的架構原理嗎?

聊一聊RocketMQ的註冊中心NameServer

Broker的主從架構是怎麼實現的?

RocketMQ生產部署架構如何設計

RabbitMQ和Kafka的高可用叢集原理

RocketMQ的傳送模式和消費模式

討論一下秒殺系統的技術難點與解決方案

秒殺系統中的扣減庫存和流量削峰

深入研究RocketMQ生產者傳送訊息的底層原理

深入研究Broker是如何持久化的

Dledger是如何實現主從自動切換的

深入研究RocketMQ消費者是如何獲取訊息的

 

相關文章