分佈式事務 -- MQ實現

場景:

訂單系統和運單系統

點外賣,用戶下單 ,下單後觸發運單系統生成運單

分佈式系統:一個請求,由多個系統協同處理完成

微服務只是架構分佈式系統的一種方法

訂單系統,調用運單系統,

程序分析:

使用RPC遠程過程調用,實現服務直接交互

分佈式事務涉及:CAP |BASE

理論是實踐之後的總結

儘管加了事務@Transaction,可是依然會發生如下異常:

訂單失敗,而運單依然有數據產生

原因是:運單系統內部處理的時候模擬耗時3秒,超過了請求時設置的超時時間2秒,所有調用方認爲沒有結果返回就認爲異常了,

其實運單服務還正常運行中。所以運單系統有了數據,而訂單系統因爲回滾,所以沒有數據


需要找一箇中間載體來規避上述這些問題:

這個載體需要具備的特性:

 

載體選擇:自研、MQ、Redis、zookeeper、數據庫

  1. 自研:seata |lcn|TCC各種框架研發
  2. Redis、zookeeper[可靠,redis、zookeeper主動內存型,數據不保證丟失]
  3. 數據庫--數據庫集羣高可用
  4. MQ--本質:和redis 、zookeeper本質一樣, 數據存取

特點:沒有要求結構化的數據

還沒有開箱即用的開源方案。針對自身的業務場景,進行定製化的解決

演示一種MQ的解決方案:

消息可發發送

可能的異常

  • MQ發送失敗
  1. mq調用成功,但是訂單事務提交失敗   --解決辦法:mq操作和訂單事務分離,把事務註解加到saveOrder方法上去,這樣就保證了,order一定插入到數據庫,纔會去執行發送消息隊列,如果order數據插入異常,則直接回滾,不去執行發送消息隊列,保證了插入order數據和消息隊列同時發生,或者同時失敗
  2. mq調用網絡不通【重發----】

    實現方式:新建一張本地消息tb_distribute_message表。【裏面需要有一個業務消息的唯一id,保證冪等】在插入訂單的同時,插入一條本地消息,並標記爲未消費,標記爲已消費的節點是,mq的ack機制,發送回執的時候

  3. Mq有ack機制[需要自己去開啓]發送以後有回執,就消息會發送到一個名字叫做orderQueue的隊列中去,會觸發一個方式confirimCallback可以修改狀態,

  4. 定時任務schedule可以去檢查這張表,消息是否發送,這樣就可以重發了
  5. 修改消息表的狀態爲已發送
  6. mq收到請求,突然斷開網絡,實際MQ已經存儲消息【如何知曉MQ是否收到消息】
  • MQ本身可靠性如何保障【自帶高可靠方案,副本】

消息可靠消費

1.運單系統配置rabbitMQ

從之前創建的隊列orderQueue中取值

1.先創建隊列

這裏涉及冪等(重複),

產生的場景:mq ack之後,返回消息給訂單系統,,此時訂單系統掛掉了,沒有收到消息,本地消息表中消息狀態仍然是未發送,這樣定時任務去掃消息表的時候,發現未發送,於是又觸發一次發送操作

運單表主鍵直接就是order_id

要有一個業務標記,能夠識別是否爲同一條數據。記錄已經處理的數據(比如用redissetNx)

 

 

還有問題,就是運單系統消費消息,處理中途,運單系統掛掉了。也就是沒有可靠消費==消費中途出了問題

可是ack是自動發送的,並不考慮消費的結果(是否可靠消費)。此時消息也被消費了。也不能再次觸發了

所以此時應該修改自動ack爲手動(代碼控制),並做後續的業務處理

看上面的代碼messageConsumer中處理

requeue = true標識重發

requeue = false標識不重發

 

兩個系統之間交互,用MQ消息隊列

用RabbitMQ,因爲和spring同一個母公司,集成非常好

有Message Queue| 有topic/queue的概念 多個queue


 

mq一般都是自動ack,容易出問題,

需要改爲手動ack.當消息正常處理後,告訴mq刪除

channel.basicAck(false);

//如果消費者突然斷電或者進程kill,MQ檢測到連接斷開,會向其他消費者重複

//出現可控的異常,告訴MQ,你幫我重發--根據具體的業務系統設計

//出現未知異常,運維日誌監控,預警機制

channel.asicNack(tag,false,"requeue":false);//丟到了垃圾堆,回收站可以找到

 

CAP=就是三選二

多系統之間肯定是通過網絡來交互,網絡是不可靠的

分區容錯:多個系統之間不能交互,仍然要對外提供服務

一致性:訂單系統和運單系統數據一致

可用性:

是對其中某一個部分做出一些犧牲,不是完全不能兼顧,要做一些取捨

 


對於大數據量併發

生產者可以分佈式部署

消費者分組group概念

所有不用擔心數據量大的問題

 

 

基於分區

Base理論:就是對CAP理論的擴展【基本可用】通過修改狀態來實現回滾

 

SAGA理論,每一個模塊都很好的工作,保證

Seata開源分佈式解決方案對之前這些操作封裝

 

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