[Java復習]分布式事務 TCC RocketMQ最終一致性


畫一下你們電商系統的核心交易鏈路圖,說說分布式架構下存在什么問題?

主要核心是要考慮分布式事務分布式鎖的問題。

分布式系統,事務 -> 分布式事務,鎖 -> 分布式鎖

 

電商核心流程:

訂單服務 -> 創建訂單 -> 庫存服務 -> 扣減庫存 -> 積分服務 -> 增加積分 -> 倉儲服務 -> 通知發貨

 

針對電商核心交易鏈路,你們是怎么設計分布式事務技術方案的?

TCC可靠消息最終一致性方案是在生產中最常用。

一個要求強一致,一個要求最終一致。

強一致主要用於核心模塊,例如交易/訂單等。最終一致一般用於邊緣模塊例如庫存,通過mq去通知,保證最終一致性,也可以業務解耦。

 

TCC:

訂單服務、庫存服務、積分服務 -> 綁定為一個TCC事務

撤銷剛才創建訂單時,回滾剛才扣減庫存和增加積分

可靠消息最終一致性:

可以去發送一個請求給消息中間件,由中間件保證一定會把消息交給下游的庫存服務去扣減庫存,倉儲服務去通知發貨等,

如果這個過程中有消息發送失敗,則可靠消息中間件應該保證不停的重試投遞消息。

 

對於TCC事務、最終一致性事務的技術選型,你們是怎么做的?如何調研的?

TCC:

阿里開源了分布式事務框架,fescar,seata。seata類似TCC事務,經歷過阿里生產環境大量考驗的框架。支持Dubbo,Spring Cloud。

可靠消息最終一致性:

基於ActiveMQ,RabbitMQ, RocketMQ等,自己開發一個可靠消息服務,收到消息之后,嘗試投遞到MQ,如果投遞失敗,重試投遞。

現在大量用RocketMQ,作為MQ中間件,提供了分布式事務支持,已經把可靠消息服務需要實現的功能邏輯已經做好了。

 

 

在搭建好的電商系統里,落地開發對交易鏈路的TCC分布式事務方案?

seata:特點:自動回滾數據庫事務。

https://github.com/seata/seata-samples.git

把seata所有的示例代碼拷貝下來,里面提供的例子就是跟我們說的電商的核心例子是類似的.

然后先要下載一個seata-server到本地,在這里下載:https://github.com/seata/seata/releases,

然后啟動起來,這是分布式事務管理中心,負責維護每一個分布式事務的狀態,觸發分布式事務的提交和回滾。

    

 

 

你能說說一個TCC分布式事務框架的核心架構原理嗎?

Seata架構原理:

https://github.com/seata/seata

Seata中角色:

Transaction Coordinator(TC):協調器,單獨的一個server。維護全局和分支事務的狀態,驅動全局事務的提交或回滾。

Transaction Manager(TM):全局事務的發起者,負責開始/提交/回滾一個全局事務。(對應訂單服務)

Resource Manager(RM):管理分支事務(注冊分支事務/狀態/提交/回滾),並負責與TC通訊。

整個使用seata進行分布式事務管理的生命周期

1、TM向TC發起全局事務,TC返回XID作為標識。

2、XID通過調用鏈傳播。

3、RM將本地的事務注冊到TC中表示為XID的全局事務中,成為一個分支事務。

4、再由TM向TC請求標識為XID的全局事務提交/回滾。

5、最終,由TC去驅動所有的分支事務提交/回滾。

 

現有的TCC事務方案的性能瓶頸在哪里?能支撐高並發交易場景嗎?如何優化?

使用分布式事務主要是保證核心鏈路要么全部成功,要么全部失敗。當然也會帶來一些性能的開銷。

seata模型里面頻繁的網絡通信,以及對應事務的狀態持久化的IO等等。

如果需要支撐高並發,那么TC服務也需要橫向擴容。相應的,對於TC背后的DB也需要進行優化。

 

RocketMQ分布式事務:

你了解RocketMQ對分布式事務支持的底層實現原理嗎?

核心鏈路使用seata這種類似於TCC的事務,而像wms這種相當於是分支鏈路,可以通過MQ進行解耦。

但是通過MQ解耦也會帶來一些問題,例如消息丟失,消息重復等等問題,因此也需要進行最終一致性的保證。

  

 

 結合整個訂單接口服務,分為兩個支付鏈路,一個是核心鏈路(訂單業務),一個是非核心鏈路(wms) 整個流程。

先向RocketMQ發送half msg,然后調用核心鏈路。核心鏈路要是返回失敗,就會走失敗的邏輯:退款,更改訂單狀態為取消,再給rocketmq發送callback廢棄掉剛才的消息。

如果成功,就commit msg讓消費者可以消費。如果在等待期間,一直沒有callback/commit那么mq就會走回調查詢具體的狀態。最終消費者接收到消息后,消費完成就回復mq一個ack, 如果消費失敗了,mq就會重新投遞或者換一個服務投遞。使用rocketmq的half msg機制,可以實現這一套固定模式的最終一致性,很完善。 這個將wms的操作放在核心鏈路前面的這個問題,是為了提升整個訂單接口服務的效率,因為需要保證最終一致性,那么必然會有消息生產者對MQ的一些操作,包括重試,ack等等,如果將這些邏輯全部都放在核心鏈路執行完成后再去一一完成,那么可能會耗費一些時間。而通過rocketmq這個模式,可以通過half msg的支持,來將整個與mq的交互過程拆解掉,從而提升效率。

  

如果公司沒有RocketMQ中間件,那你們如何實現最終一致性事務?

基於數據庫自己開發一個可靠消息服務。接受上游Producer發送的haf msg, 存入DB,返回響應。本地可靠消息服務啟動定時掃描本地DB的half msg,超過一定時間沒有commit/rollback就回調Producer接口,確認本地事務是否成功,獲取commit/rollback。如果消息commit就發送消息給下游服務或者發給RabbitMQ/Kafka/ActiveMQ,下游服務消費后,回調可靠消息服務接口進行ack,如果沒有收到ack,重發消息給下游服務。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM