RabbitMQ 消息 100% 投遞的解決方案!

Java技術(shù)棧
www.javastack.cn
關(guān)注閱讀更多優(yōu)質(zhì)文章
一、前言
現(xiàn)在大多都使用 MQ 來(lái)做系統(tǒng)的異構(gòu),來(lái)做系統(tǒng)的解耦,系統(tǒng)的的模塊相當(dāng)于寄信者與收信者,MQ 則扮演者郵局的角色。作為一個(gè)中轉(zhuǎn)的角色,就需要確保消息的100%投遞。
今天我們就來(lái)研究一下如何確保消息的100%的投遞。
二、先談?wù)?RabbitMQ 的特性
RabbitMQ 所做的確保是:只要你把消息投遞到 Broker 中,那么我就確保這個(gè)消息會(huì)送達(dá)到消費(fèi)者的手中。
當(dāng)然這是有前提條件的,比如:
你需要進(jìn)行手動(dòng)應(yīng)答, 最起碼 Broker 不掛,且消息進(jìn)行了持久化等。
結(jié)合 RabbitMQ 的特性來(lái)做分析,針對(duì)于投遞端,我們只需要確保把消息發(fā)送到 Broker 中即可,那么如何保證可靠性呢,分下列步驟:
消息成功的發(fā)送了出去 保證 Broker 成功的收到了消息 生產(chǎn)者收到了 Broker 的確認(rèn)應(yīng)答 消息補(bǔ)償機(jī)制,當(dāng)前三步都跪了,做一個(gè)補(bǔ)償重發(fā)機(jī)制 最后一道屏障,如果第四步重試次數(shù)過(guò)多,那么說(shuō)明系統(tǒng)出現(xiàn)問(wèn)題,我們就需要人工干預(yù)了
只要做到上面五步,基本上我們就可以保證,消息投遞100%的投遞出去。另外,關(guān)注公眾號(hào)Java技術(shù)棧,在后臺(tái)回復(fù):面試,可以獲取我整理的 RabbitMQ 系列面試題和答案,非常齊全。
三、生產(chǎn)者的投遞的可靠性保障
3.1 先上一個(gè)示意圖
3.2 就上述的圖示,我們逐步解析
step1:數(shù)據(jù)落庫(kù),這一步是必須的 step2:把消息落庫(kù),且初始化其狀態(tài)為 0 (發(fā)送中) step3:把消息投遞到 Broker 中 step4:Broker 發(fā)送成功應(yīng)答 step5:生產(chǎn)者拿到成功應(yīng)答,修改消息狀態(tài)為1:(發(fā)送成功) 上面講述的都是正常的流程,下面講講如果出現(xiàn)不正常的解決機(jī)制: step6:定時(shí)檢查消息的狀態(tài)是否為1 step7:如果 step6 的消息的狀態(tài)仍然為 0 ,則進(jìn)入重發(fā),重復(fù)上述 step1 - step5 step8:如果消息重發(fā)達(dá)到一定的的次數(shù),則人工接入處理,因?yàn)榇藭r(shí)說(shuō)明可能是消息
上述的方案看似完美無(wú)缺,但是細(xì)想,如果在 step4 中 Broker 發(fā)送應(yīng)答的過(guò)程中,網(wǎng)絡(luò)出現(xiàn)問(wèn)題這個(gè)消息沒(méi)有到達(dá)生產(chǎn)者會(huì)導(dǎo)致整個(gè)流程進(jìn)入補(bǔ)償?shù)牧鞒坍?dāng)中,此時(shí) Broker 中就有兩條消息,也就是發(fā)成了重復(fù)的投遞的問(wèn)題,所以接下來(lái)我們要在消費(fèi)端來(lái)處理這個(gè)問(wèn)題。
四、消費(fèi)端的冪等:
4.1 導(dǎo)致需要解決冪等的原因
Broker 發(fā)送應(yīng)答消息的時(shí)候,消息未到達(dá)生產(chǎn)者 消費(fèi)者在發(fā)送應(yīng)答的時(shí)候,消費(fèi)者掛掉了
4.2 就上述我們的機(jī)制的解決
因?yàn)樯鲜鑫业南⒍加形ㄒ坏臉?biāo)識(shí),所以我們只需要查找對(duì)應(yīng)的消息對(duì)應(yīng)的標(biāo)識(shí)來(lái)判斷其狀態(tài)即可。
4.3 構(gòu)建唯一標(biāo)識(shí)的方案
首先說(shuō)明不同的方案使用不同的應(yīng)用場(chǎng)景,不要一上來(lái)你就說(shuō)十幾萬(wàn)的并發(fā)怎么樣的,這個(gè)慢慢來(lái),一步步往這里走。
4.3.1 利用數(shù)據(jù)庫(kù)自增id
優(yōu)點(diǎn):
1):不能再簡(jiǎn)單了,在并發(fā)不大的情況可以接受
2):對(duì)分頁(yè)和排序是有幫助的
缺點(diǎn):
1):分庫(kù)分表和讀寫分離多住從的情況下不適用
2):性能達(dá)不到要求時(shí),不利于擴(kuò)展
3):不同數(shù)據(jù)庫(kù)的語(yǔ)法實(shí)現(xiàn)不一樣
4.3.2 利用 redis 來(lái)生成id
優(yōu)點(diǎn):
缺點(diǎn):
1):引入新的組件,增加系統(tǒng)復(fù)雜度
2):需要注意處理并發(fā)問(wèn)題
4.3.3 利用 twitter 開(kāi)源的 snowflake
snowflake 是 twitter 開(kāi)源的一個(gè)分布式的 ID 的生成算法,結(jié)果是一個(gè) long 的ID,使用 41bit 作為毫秒數(shù),10bit 作為機(jī)器 ID(5個(gè) bit 是數(shù)據(jù)中心,5個(gè) bit 是機(jī)器 ID) 12 bit 作為毫秒內(nèi)的流水號(hào)(每個(gè)節(jié)點(diǎn)每毫秒可以產(chǎn)生 2^12 = 4096 個(gè) ID)最后是一個(gè)符號(hào)位。
優(yōu)點(diǎn):
不依賴數(shù)據(jù)庫(kù)和其他的中間件,且性能尚可
缺點(diǎn):
是有依賴時(shí)間的,如果各個(gè)機(jī)器的失重不同步就會(huì)出現(xiàn)不適全局遞增的情況。
最后,關(guān)注公眾號(hào)Java技術(shù)棧,在后臺(tái)回復(fù):面試,可以獲取我整理的 RabbitMQ 系列面試題和答案,非常齊全。
作者:熱心市民小陳
鏈接:blog.csdn.net/weixin_42849915/article/details/87828163
版權(quán)聲明:本文為博主原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接和本聲明。






關(guān)注Java技術(shù)??锤喔韶?/strong>


