1. 程式人生 > >RocketMQ及分散式訊息系統的原理以及重要問題解讀

RocketMQ及分散式訊息系統的原理以及重要問題解讀

看到一篇好文章,記錄一下:http://www.jianshu.com/p/453c6e7ff81c

先總結下他的解決方案:

把訊息順序放到 業務層去實現,同時解決訊息重複的問題(因為其最終目標是要叢集的高容錯性和高吞吐量,因為為了保證順序,mq server必定要與每一個消費端進行多次溝通,一個訊息消費完,才傳送另一個訊息,這樣並行效能註定低下
解決訊息重複2 個方案,1. 訊息冪等,2 訊息日誌(記錄訊息應用狀態)


本文把訊息事務(分散式訊息一般要考慮 訊息順序和訊息重複的處理)、分散式事務,說的很透徹,值得一讀。

訊息事務的拆解:分散式訊息事務涉及到的producer, broker之間的事務確認和重要互動
訊息沒有按時到broker,則broker記錄並回查自己這邊的事務狀態,如果是需要詢問的狀態(Prepared)則詢問producer的事務介面,兩邊進行事務狀態的通訊,broker問producer:你是發起方,你那邊是否ok,producer根據事務策略來進行決策,最後通知broker更新訊息的最終狀態。 原文流程:如果endTransaction方法執行失敗,資料沒有傳送到broker,導致事務訊息的 狀態更新失敗,broker會有回查執行緒定時(預設1分鐘)掃描每個儲存事務狀態的表格檔案,如果是已經提交或者回滾的訊息直接跳過,如果是prepared狀態則會向Producer發起CheckTransaction請求,Producer會呼叫DefaultMQProducerImpl.checkTransactionState()方法來處理broker的定時回撥請求,而checkTransactionState會呼叫我們的事務設定的決斷方法來決定是回滾事務還是繼續執行,最後呼叫endTransactionOneway讓broker來更新訊息的最終狀態。
執行流程:第一階段 先Prepare(拿到訊息地址),第二階段 保證本地事務成功,再發送訊息,第三階段 根據Prepare訊息地址,修改訊息狀態,最後確認訊息已傳送。如果確認訊息確認失敗,“訊息叢集掃描Prepare訊息地址,這時候發現了Prepared訊息,它會向訊息傳送者確認,如果本地事務成功(扣款成功),訊息傳送失敗,是回滾還是繼續傳送確認訊息呢? RocketMQ會根據傳送端設定的策略來決定是回滾還是繼續傳送確認訊息。這樣就保證了訊息傳送與本地事務同時成功或同時失敗。
如果訊息傳送成功,但是消費失敗,一般不考慮在分散式系統中去實現整個過程的回滾,可以通過提醒、監控協助“人工回滾” 最重要的是:我覺得這篇文章提供了一個思路,如果一個問題一定會出現,那就去讓這個問題出現,然後想辦法去處理出現之後的結果。