RocketMQ消息丟失解決方案:事務消息

 

前言

上篇文章,王子通過一個小案例和小夥伴們一起分析了一下消息是如何丟失的,但沒有提出具體的解決方案。

我們已經知道發生消息丟失的原因大體上分爲三個部分:

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

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

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

接下來我們就針對第一種情況,聊一聊如何解決生產者發送消息過程中的消息丟失問題。

 

先發送half消息到MQ

針對於這一問題,RocketMQ是自帶一套解決方案的,就是事務消息。今天我們就來看一下事務消息的實現流程。

案例還是上次的案例,當用戶通過訂單系統下訂單支付的時候,在訂單支付成功後,會發送消息給MQ,但是這樣的流程是無法保證事務性的。

當我們引入事務消息後,其實訂單系統是不會先去執行CRUD的操作的,而是先發送一條half消息給MQ,這個half消息其實就是訂單完成支付的消息,你可以理解爲它的狀態是half狀態。

而積分系統是無法消費half狀態的消息的。

訂單系統發送了half消息後就會等待MQ給出成功的響應,如下圖:

看到這裏有些小夥伴可能會問,爲什麼要發送half消息呢?

其實大家可以想一下,假如我們不發送half消息,直接去操作數據庫,把訂單支付業務走完,然後再去發送消息給MQ,結果發送過程中發生了異常,這就導致了積分系統無法消費到消息,就會導致支付成功,而積分沒有發放的情況。

所以我們先發一條half消息,就是爲了先確認一下能否正常發送消息,或者說確認MQ是不是還活着,並且告訴MQ接下來的消息很重要,不能丟失掉。

 

 

half消息寫入失敗怎麼辦

half消息的發送也是可能失敗的,可能因爲報錯、MQ自己掛了、或者網絡原因導致消息發送失敗。

那訂單系統就會得到這一反饋,接着就應該進行回滾操作,比如訂單關閉,退款等操作。

 

 

 

half消息寫入成功,並得到響應

那麼假如half消息發送成功,並得到了成功的響應後,訂單系統應該怎麼做呢?

這個時候,訂單系統就應該去操作數據庫,完成自己的業務功能了。

因爲half消息發送成功,表示MQ可以正常接收消息。

 

 

 

half消息寫入成功,沒有得到響應

那麼假如half消息發送成功,但是沒有得到MQ的成功響應,會怎麼辦呢?

這個時候,half消息已經正常的存儲到了MQ中,但訂單系統遲遲不能得到響應,可能會報一些網絡超時的錯誤,訂單系統就去執行回滾操作了。

那麼對於這條half消息該怎麼處理呢?

這就要說到RocketMQ的補償機制了,它會去掃描half消息,如果這條half消息遲遲沒有被rollback或者commit,一定時間後就會回調訂單系統的一個補償接口,判斷一下這步操作是成功了還是失敗了。

如果成功了,那就重新發送commit消息給MQ,失敗了,重新發送rollback消息給MQ。後文會介紹rollback和commit消息。

 

 

數據庫操作發生異常

那麼接下來如果訂單系統在執行數據庫的時候發生了異常怎麼辦呢?

這個時候數據庫本身是有事務機制的,同時我們再發送一條rollback消息給MQ就可以了。

這個時候MQ接收到rollback消息後,就會把之前的half消息給作廢掉了。

 

 

訂單業務完成後

那麼訂單系統自己的業務成功完成後接着做什麼呢?

這個時候就要發送一條commit消息給MQ了,讓MQ把之前的half消息執行commit操作,之後積分系統就可以看到這條消息了。

 

 

 

rollback或者commit消息發送失敗怎麼辦

rollback或者commit消息也是可能發送失敗的,這個時候其實也很簡單。

上文中我們已經說到了RocketMQ的補償機制,所以無論訂單系統本身是要發送rollback消息還是commit消息,如果發送失敗,MQ的補償機制就會掃描這條half消息,一定時間之後回調訂單系統的補償接口,判斷執行是否成功了,然後重新發送消息給MQ就可以了

 

 

總結

今天我們通過對RocketMQ發送消息這一過程進行各種情況的分析,會發現,開啓事務消息流程後,生產者發送消息到MQ這一過程的消息可靠性是可以得到保證的。

如果有小夥伴覺得有些情況還是沒有考慮到,歡迎評論區留言一起討論。

下篇文章我們將深入探索一下事務消息的底層實現原理,歡迎小夥伴們圍觀。

 

 

往期文章推薦:

RocketMQ的發送模式和消費模式

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

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

深入研究RocketMQ生產者發送消息的底層原理

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

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

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

RocketMQ的消息是怎麼丟失的

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章