RabbitMQ消息可靠性投遞
點擊上方藍(lán)色字體,選擇“標(biāo)星公眾號”
優(yōu)質(zhì)文章,第一時間送達(dá)
一般的消息中間件(MQ)只能保證消息不丟,但是不能保證重復(fù)發(fā)送等問題。
比如在使用Rabbitmq過程中,如何保證消息都能正確的投遞被消費,這個是要考慮的問題。
那么可靠性投遞所面臨的問題有哪些?
1. 如果發(fā)送的消息重復(fù)怎么辦。
2. 如果消息發(fā)送過程中丟了怎么辦。
3. 如何保證MQ節(jié)點成功收到消息。
針對這個問題RabbitMQ提供了以下幾個機(jī)制來解決:
生產(chǎn)者確認(rèn)
持久化
手動Ack
下圖是Rabbitmq一個完整的消息可靠投遞的一個方案。

我們來分析下。
Step1:Producer所發(fā)送的數(shù)據(jù)是我們的業(yè)務(wù)數(shù)據(jù),比如訂單信息。Producer在發(fā)送消息之前給我們的訂單信息寫入我們的本地數(shù)據(jù)庫(BIZ DB)中,BIZ DB是我們的業(yè)務(wù)數(shù)據(jù)庫,接著將要發(fā)送到消息存儲到消息記錄數(shù)據(jù)庫中(MSG DB),這個MSG DB就是存儲所有發(fā)送給Rabbitmq的消息記錄用的,寫入消息記錄表中該記錄字段status(狀態(tài))會有幾個值,比如0表示消息發(fā)送中,1表示發(fā)送成功,2表示消息發(fā)送失敗,。
Step2:應(yīng)用程序要消息發(fā)送給Rabbitmq的Broker,這個發(fā)送的消息屬于confirm模式,發(fā)送后需要Rabbitmq確認(rèn)。
Step3:Rabbitmq Broker收到消息后會給Producer一個應(yīng)答來確認(rèn)信息,說我已經(jīng)收到消息了。
Step4:緊跟上一步,Producer一直在監(jiān)聽(Listener)Broker所確認(rèn)的信息,在收到消息之后,根據(jù)收到消息的結(jié)果再去更新MSG DB中的消息發(fā)送狀態(tài),將記錄status字段更新為1。
Step 5:但是在消息確認(rèn)這個過程中可能由于網(wǎng)絡(luò)閃斷、MQ Broker端異常等原因?qū)е?回送消息失敗或者異常。這個時候就需要發(fā)送方(生產(chǎn)者)對消息進(jìn)行可靠性投遞了,保障消息不丟失,100%的投遞成功?。ㄓ幸环N極限情況是閃斷,Broker返回的成功確認(rèn)消息,但是生產(chǎn)端由于網(wǎng)絡(luò)閃斷沒收到,這個時候重新投遞可能會造成消息重復(fù),需要消費端去做冪等處理)所以我們需要有一個定時任務(wù),(比如每5分鐘拉取一下處于中間狀態(tài)的消息,當(dāng)然這個消息可以設(shè)置一個超時時間,比如超過1分鐘 Status = 0 ,也就說明了1分鐘這個時間窗口內(nèi),我們的消息沒有被確認(rèn),那么會被定時任務(wù)拉取出來)。
Step 6:接下來我們把中間狀態(tài)的消息進(jìn)行重新投遞 retry send,繼續(xù)發(fā)送消息到MQ ,當(dāng)然也可能有多種原因?qū)е掳l(fā)送失敗
Step 7:我們可以采用設(shè)置最大努力嘗試次數(shù),比如投遞了3次,還是失敗,那么我們可以將最終狀態(tài)設(shè)置為Status = 2 ,最后 交由人工解決處理此類問題(或者把消息轉(zhuǎn)儲到失敗表中)。
作者:阿神
鏈接:https://www.imooc.com/article/49814
來源:慕課網(wǎng)
本文原創(chuàng)發(fā)布于慕課網(wǎng) ,轉(zhuǎn)載請注明出處,謝謝合作
粉絲福利:Java從入門到入土學(xué)習(xí)路線圖
??????

??長按上方微信二維碼 2 秒
感謝點贊支持下哈 
