mq日志怎么看_RocketMQ的消息是怎么丢失的
前言
通過之前文章的閱讀,有關(guān)RocketMQ的底層原理相信小伙伴們已經(jīng)有了一個(gè)比較清晰的認(rèn)識(shí)。
那么接下來王子想跟大家討論一個(gè)話題,如果我們的項(xiàng)目中引入了MQ,勢(shì)必要面對(duì)的一個(gè)問題,就是消息丟失問題,今天我們就來聊聊消息是怎么丟失的。
現(xiàn)在假設(shè)我們的業(yè)務(wù)是這樣的,用戶通過訂單系統(tǒng)下了一個(gè)訂單,訂單系統(tǒng)完成支付后會(huì)發(fā)送消息給RocketMQ,然后積分系統(tǒng)會(huì)從RocketMQ中消費(fèi)消息,去給用戶增加積分,如下圖:
但是突然有一天有用戶反映,支付訂單之后,自己的積分并沒有增長,這是為什么呢?
經(jīng)過排查日志,我們只發(fā)現(xiàn)了推送消息給MQ的日志,而沒有發(fā)現(xiàn)積分系統(tǒng)消費(fèi)這條消息的日志,這就導(dǎo)致了積分系統(tǒng)并沒有給用戶發(fā)放積分。
也就是說,消息在傳輸過程中丟失了。
在系統(tǒng)的核心鏈路中,如果發(fā)生消息丟失的問題,可能會(huì)產(chǎn)生惡劣的后果,為了解決此類問題,我們必須弄明白什么時(shí)候會(huì)發(fā)生消息丟失。
我這準(zhǔn)備了一份大廠面試題 最新的 覆蓋了多項(xiàng)技術(shù)面試的考題 需要的小伙伴
轉(zhuǎn)發(fā)+關(guān)注 私信我【666】免費(fèi)獲取
訂單系統(tǒng)推送消息過程中會(huì)丟失消息嗎?
我們先來看一下整個(gè)流程的第一步,訂單系統(tǒng)在支付成功之后,一定會(huì)把支付成功的消息推送給MQ,那么在這個(gè)推送的過程中,消息可能丟失嗎?
答案是肯定的,一定會(huì)存在消息丟失的情況。
比較常見的情況就是網(wǎng)絡(luò)抖動(dòng),在推送消息這一過程中是通過網(wǎng)絡(luò)進(jìn)行通信的,那么這個(gè)時(shí)候如果恰巧網(wǎng)絡(luò)出現(xiàn)了故障,導(dǎo)致通信失敗了,那么這個(gè)消息必然就不會(huì)成功的推送到MQ中。
那除了網(wǎng)絡(luò)抖動(dòng)外,還有沒有其他的情況導(dǎo)致推送失敗呢?
其實(shí)情況有很多,比如MQ成功接收到了消息,但是MQ本身的網(wǎng)絡(luò)模塊的代碼出現(xiàn)了異常,可能是內(nèi)部實(shí)現(xiàn)的bug,導(dǎo)致消息沒有成功處理。
或者當(dāng)我們推送消息給一個(gè)MQ的主從集群的時(shí)候,剛好遇到Leader節(jié)點(diǎn)出現(xiàn)故障,其他的Follower正在嘗試切換為Leader,這個(gè)過程中也可能導(dǎo)致消息丟失。
類似的問題還有其他的。
所以我們首先要明確一點(diǎn),無論我們使用任何MQ中間件的時(shí)候,你發(fā)送出的消息都不一定能成功,而失敗的時(shí)候有可能會(huì)在你的代碼里發(fā)生異常,也有可能不會(huì)拋出異常,具體要看什么情況導(dǎo)致的發(fā)送失敗。
MQ接收到消息后,自己會(huì)把消息弄丟嗎?
接下來假設(shè)我們訂單系統(tǒng)推送到MQ這一過程沒有任何問題,消息成功到達(dá)了MQ中,此時(shí)訂單系統(tǒng)會(huì)認(rèn)為消息寫入成功了,那么這時(shí)候消息就一定不會(huì)丟失了嗎?
答案是否定的,這個(gè)時(shí)候也不能保證消息的不丟失,我們來分析一下。
通過之前文章的了解,相信大家都還記得,當(dāng)消息寫入到MQ后,MQ會(huì)把消息先寫入到os cache,也就是操作系統(tǒng)的緩存區(qū)中,本質(zhì)也是內(nèi)存,如下圖:
也就是說,你認(rèn)為發(fā)送成功的消息,可能只存在于內(nèi)存中,還沒到磁盤中。
那么如果這個(gè)時(shí)候機(jī)器宕機(jī)了,os cache中的消息數(shù)據(jù)將會(huì)跟著丟失掉,是不是這個(gè)理。
那么現(xiàn)在假設(shè)消息已經(jīng)刷新到磁盤上了,是不是就可以保證萬無一失了呢?
顯然這個(gè)時(shí)候也是不能完全保證的,因?yàn)殡m然你把數(shù)據(jù)保存到了磁盤中,但是如果磁盤發(fā)生了故障,數(shù)據(jù)還是會(huì)丟失掉。
如果大家平時(shí)有了解一下新聞熱點(diǎn),會(huì)聽說過某某互聯(lián)網(wǎng)公司,由于數(shù)據(jù)存儲(chǔ)在磁盤上沒有冗余備份,結(jié)果磁盤發(fā)生故障導(dǎo)致好多年的核心數(shù)據(jù)全部丟失,大量工作都功虧一簣,這就是血淋淋的教訓(xùn)。
積分系統(tǒng)消費(fèi)到了消息就能保證消息的不丟失了嗎?
那么到現(xiàn)在,經(jīng)歷了重重困境,假設(shè)積分系統(tǒng)終于能夠消費(fèi)到這條消息了,那么它就能安穩(wěn)的把積分正常的發(fā)放給用戶嗎?
答案依然是否定的。
看過之前文章的小伙伴們應(yīng)該還記得消費(fèi)者在進(jìn)行消費(fèi)時(shí),是有一個(gè)offset的概念的。
這個(gè)offset說白了就是個(gè)進(jìn)度標(biāo)識(shí),讓MQ知道消費(fèi)者消費(fèi)到了哪,下次好接著向下消費(fèi)。
現(xiàn)在假設(shè)我們有兩條消息,offset為1和2。
假設(shè)我們的積分系統(tǒng)接收到了消息1,那么消息1就在積分系統(tǒng)的內(nèi)存中,正要準(zhǔn)備給用戶發(fā)放積分。
而默認(rèn)情況下,消費(fèi)者會(huì)自動(dòng)提交已經(jīng)消費(fèi)的消息的offset,所以當(dāng)積分系統(tǒng)獲取消息后,可能直接就把消息1的offset提交給了MQ,標(biāo)識(shí)為已經(jīng)處理了這條消息。
那么此時(shí),如果積分系統(tǒng)突然宕機(jī),還未發(fā)放積分給用戶,那么這條消息1自然就丟失了,因?yàn)镸Q已經(jīng)把他標(biāo)記成了已處理,實(shí)際積分系統(tǒng)還未處理。
所以消費(fèi)者獲得消息后也是可能發(fā)生消息丟失的。
總結(jié)
好了,看過今天的文章,相信小伙伴們對(duì)于RocketMQ的消息是怎么丟失的會(huì)有一個(gè)更深刻的印象。
總結(jié)起來就是以下幾點(diǎn):
1.生產(chǎn)者發(fā)送消息到MQ這一過程導(dǎo)致消息丟失
2.MQ自己發(fā)生故障導(dǎo)致消息丟失
3.消費(fèi)者拿到消息后,由于操作不當(dāng)導(dǎo)致消息丟失
所以任何的技術(shù)引入生產(chǎn)環(huán)境都是有風(fēng)險(xiǎn)的,引入前我們一定要做好功課。
今天的文章就說到這,小伙伴們可能會(huì)問王子,聊了這么多,到底應(yīng)該如何解決掉消息丟失的問題呢?
總結(jié)
以上是生活随笔為你收集整理的mq日志怎么看_RocketMQ的消息是怎么丢失的的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python3标准库书怎么样_Pytho
- 下一篇: usestate中的回调函数_React