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

王子發表於2020-10-13

 

前言

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

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

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的訊息是怎麼丟失的

 

相關文章