04消息發送一致性(可靠消息的前提保障)

消息中間件的應用場景

消息中間件在分佈式系統的中主要做用:異步通信、解耦、併發緩衝java

如圖:經過引入消息中間件來解耦應用間(服務間)的直接調用,同時也會起到異步通信和緩衝併發的做用網絡

消息發送和投遞的不可靠性

分佈式部署環境下,須要經過網絡進行通信,就引入了數據傳輸的不肯定性
也就是CAP理論中的P(分區容錯性的問題)
併發

消息發送一致性

消息發送一致性:是指產生消息的業務動做與消息發送的一致。
(也就是說,若是業務操做成功,那麼由這個業務操做所產生的消息必定要成功投遞出去,不然就丟消息)
異步

消息發送一致性如何保障?

  • 處理方式一
/** 支付訂單處理**/
public void completeOrder() {
   // 訂單處理(業務操做)
   orderBiz.process();
   // 發送會記原始憑證消息(發送消息)
   sendAccountingVoucherMsg();
}

一、若是業務操做成功,執行消息發送前應用故障,消息發不出去,致使消息丟失(訂單系統與會計系統的數據不一致);
二、若是業務操做成功,應用正常,但消息系統故障或網絡故障,也會致使消息發不出去(訂單系統與會計系統的數據不一致);分佈式

  • 處理方式二
/** 支付訂單處理**/
public void completeOrder() {
   // 發送會記原始憑證消息(發送消息)
   sendAccountingVoucherMsg();
   // 訂單處理(業務操做)
   orderBiz.process();
}

一、這種狀況下,更不可控,消息發出去了,但業務可能會失敗(訂單系統與會計系統的數據不一致);性能

前面兩種方式,都不能保證業務數據的一致性。
還有沒有其餘辦法?
spa

 

JMS標準中的XA協議方式是否能夠保障發送一致性?

JMS協議標準的API中,有不少以XA開頭的接口,其實就是前面課程講到的支持XA協議(基於兩階段提交協議)的全局事務型接口。
JMS中的XA系列接口,能夠提供分佈式事務支持。
但引用了XA方式的分佈式事務,又會帶來不少的侷限:
  •要求業務操做的資源必須支持XA協議(並非全部資源都支持XA)
  •兩階段提交協議的成本
  •持久化成本等DTP模型的侷限性(全局鎖定,成本高,性能低)code

引入XA,違背了柔性事務的初衷!中間件

消息發送一致性:變通的作法

1. 主動方應用先把消息發給消息中間件,消息狀態標記爲「待確認」;
2. 消息中間件收到消息後,把消息持久化到消息存儲中,但並不向被動方應用投遞消息;
3. 消息中間件返回消息持久化結果(成功/失敗),主動方應用根據返回結果進行判斷如何進行業務操做處理:
a) 失敗:放棄業務操做處理,結束(必要時向上層返回失敗結果);
b) 成功:執行業務操做處理;
4. 業務操做完成後,把業務操做結果(成功/失敗)發送給消息中間件;
5. 消息中間件收到業務操做結果後,根據業務結果進行處理;
a) 失敗:刪除消息存儲中的消息,結束;
b) 成功:更新消息存儲中的消息狀態爲「待發送(可發送)」,緊接着執行消息投遞;
6. 前面的正向流程都成功後,向被動方應用投遞消息;接口

消息發送一致性方案的正向流程是可行的,但異常流程怎麼處理呢? 消息發送到消息中間件中能獲得保障了,但消息的準確消費(投遞)又如何保障呢? 有沒有支持這種發送一致性流程的現成消息中間件?

相關文章
相關標籤/搜索