Python知識分享網(wǎng) - 專業(yè)的Python學習網(wǎng)站 學Python,上Python222
RocketMQ實踐:確保消息不丟失與順序性的高效策略 PDF 下載
匿名網(wǎng)友發(fā)布于:2024-01-05 09:59:32
(侵權(quán)舉報)
(假如點擊沒反應(yīng),多刷新兩次就OK!)

RocketMQ實踐:確保消息不丟失與順序性的高效策略 PDF 下載  圖1

 

 

 

資料內(nèi)容:

 

2、RocketMQ消息零丟失方案
1》 生產(chǎn)者使用事務(wù)消息機制保證消息零丟失
這個結(jié)論比較容易理解,因為RocketMQ的事務(wù)消息機制就是為了保證零丟失來設(shè)計的,并且經(jīng)過阿里
的驗證,肯定是非??孔V的。
但是如果深入一點的話,我們還是要理解下這個事務(wù)消息到底是不是靠譜。我們以最常見的電商訂單場
景為例,來簡單分析下事務(wù)消息機制如何保證消息不丟失。我們看下下面這個流程圖:

1、為什么要發(fā)送個half消息?有什么用?
這個half消息是在訂單系統(tǒng)進行下單操作前發(fā)送,并且對下游服務(wù)的消費者是不可見的。那這個消息的
作用更多的體現(xiàn)在確認RocketMQ的服務(wù)是否正常。相當于嗅探下RocketMQ服務(wù)是否正常,并且通知
RocketMQ,我馬上就要發(fā)一個很重要的消息了,你做好準備。
2.half消息如果寫入失敗了怎么辦?
如果沒有half消息這個流程,那我們通常是會在訂單系統(tǒng)中先完成下單,再發(fā)送消息給MQ。這時候?qū)?br /> 入消息到MQ如果失敗就會非常尷尬了。而half消息如果寫入失敗,我們就可以認為MQ的服務(wù)是有問題
的,這時,就不能通知下游服務(wù)了。我們可以在下單時給訂單一個狀態(tài)標記,然后等待MQ服務(wù)正常后
再進行補償操作,等MQ服務(wù)正常后重新下單通知下游服務(wù)。
3.訂單系統(tǒng)寫數(shù)據(jù)庫失敗了怎么辦?
這個問題我們同樣比較下沒有使用事務(wù)消息機制時會怎么辦?如果沒有使用事務(wù)消息,我們只能判斷下
單失敗,拋出了異常,那就不往MQ發(fā)消息了,這樣至少保證不會對下游服務(wù)進行錯誤的通知。但是這
樣的話,如果過一段時間數(shù)據(jù)庫恢復過來了,這個消息就無法再次發(fā)送了。當然,也可以設(shè)計另外的補
償機制,例如將訂單數(shù)據(jù)緩存起來,再啟動一個線程定時嘗試往數(shù)據(jù)庫寫。而如果使用事務(wù)消息機制,
就可以有一種更優(yōu)雅的方案。
如果下單時,寫數(shù)據(jù)庫失敗(可能是數(shù)據(jù)庫崩了,需要等一段時間才能恢復)。那我們可以另外找個地方
把訂單消息先緩存起來(Redis、文本或者其他方式),然后給RocketMQ返回一個UNKNOWN狀態(tài)。這樣
RocketMQ就會過一段時間來回查事務(wù)狀態(tài)。我們就可以在回查事務(wù)狀態(tài)時再嘗試把訂單數(shù)據(jù)寫入數(shù)據(jù)
庫,如果數(shù)據(jù)庫這時候已經(jīng)恢復了,那就能完整正常的下單,再繼續(xù)后面的業(yè)務(wù)。這樣這個訂單的消息
就不會因為數(shù)據(jù)庫臨時崩了而丟失。
4.half消息寫入成功后RocketMQ掛了怎么辦?
我們需要注意下,在事務(wù)消息的處理機制中,未知狀態(tài)的事務(wù)狀態(tài)回查是由RocketMQ的Broker主動發(fā)
起的。也就是說如果出現(xiàn)了這種情況,那RocketMQ就不會回調(diào)到事務(wù)消息中回查事務(wù)狀態(tài)的服務(wù)。這
時,我們就可以將訂單一直標記為"新下單"的狀態(tài)。而等RocketMQ恢復后,只要存儲的消息沒有丟
失,RocketMQ就會再次繼續(xù)狀態(tài)回查的流程。
5.下單成功后如何優(yōu)雅的等待支付成功?
在訂單場景下,通常會要求下單完成后,客戶在一定時間內(nèi),例如10分鐘,內(nèi)完成訂單支付,支付完成
后才會通知下游服務(wù)進行進一步的營銷補償。
如果不用事務(wù)消息,那通常會怎么辦?
最簡單的方式是啟動一個定時任務(wù),每隔一段時間掃描訂單表,比對未支付的訂單的下單時間,將超過
時間的訂單回收。這種方式顯然是有很大問題的,需要定時掃描很龐大的一個訂單信息,這對系統(tǒng)是個
不小的壓力。
那更進一步的方案是什么呢?是不是就可以使用RocketMQ提供的延遲消息機制。往MQ發(fā)一個延遲1分
鐘的消息,消費到這個消息后去檢查訂單的支付狀態(tài),如果訂單已經(jīng)支付,就往下游發(fā)送下單的通知。
而如果沒有支付,就再發(fā)一個延遲1分鐘的消息。最終在第十個消息時把訂單回收。這個方案就不用對
全部的訂單表進行掃描,而只需要每次處理一個單獨的訂單消息。
那如果使用上了事務(wù)消息呢?我們就可以用事務(wù)消息的狀態(tài)回查機制來替代定時的任務(wù)。在下單時,給
Broker返回一個UNKNOWN的未知狀態(tài)。而在狀態(tài)回查的方法中去查詢訂單的支付狀態(tài)。這樣整個業(yè)
務(wù)邏輯就會簡單很多。我們只需要配置RocketMQ中的事務(wù)消息回查次數(shù)(默認15次)和事務(wù)回查間隔時
間(messageDelayLevel),就可以更優(yōu)雅的完成這個支付狀態(tài)檢查的需求。
6、事務(wù)消息機制的作用
整體來說,在訂單這個場景下,消息不丟失的問題實際上就還是轉(zhuǎn)化成了下單這個業(yè)務(wù)與下游服務(wù)的業(yè)
務(wù)的分布式事務(wù)一致性問題。而事務(wù)一致性問題一直以來都是一個非常復雜的問題。而RocketMQ的事
務(wù)消息機制,實際上只保證了整個事務(wù)消息的一半,他保證的是訂單系統(tǒng)下單和發(fā)消息這兩個事件的事
務(wù)一致性,而對下游服務(wù)的事務(wù)并沒有保證。但是即便如此,也是分布式事務(wù)的一個很好的降級方案。
目前來看,也是業(yè)內(nèi)最好的降級方案