<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          那些用Go實現(xiàn)的分布式事務(wù)框架(二)

          共 2542字,需瀏覽 6分鐘

           ·

          2021-12-28 17:06

          開篇

          上一篇那些用Go實現(xiàn)的分布式事務(wù)框架我們主要介紹的是seata-golang。一個對標seata的go語言實現(xiàn),當然版本還是落后Java版很多的。


          這次我們來介紹一下另一個go實現(xiàn)的分布式事務(wù):dtm。

          首先來看下dtm整體架構(gòu)圖(來源官網(wǎng))。



          再來看之前的seata架構(gòu)圖

          從架構(gòu)上來看,大差不差。


          seata中的TC對標dam的TM。


          RM兩邊意思一致。


          seata中的TM對標dtm事務(wù)SDK。作用都是一樣:第一階段開啟一個全局事務(wù),執(zhí)行各RM分支事務(wù),第二階段根據(jù)RM第一階段執(zhí)行結(jié)果,決定調(diào)用TC(seata)|TM(dtm) commit或者rollback。


          架構(gòu)上,個人感覺只是因為模塊名稱以及圖畫不一樣的差別,當然在實現(xiàn)細節(jié)上還是有很大差別的。


          我們先簡單介紹下DTM各個模塊。


          TM

          TM 層在代碼中是沒有具體的主體結(jié)構(gòu)的,開始都是函數(shù)之前的調(diào)用。


          啟動TM實際上開啟了兩個服務(wù),http以及grpc這兩個服務(wù)

          http路由,

          gRPC接口

          即然提供了兩個服務(wù)入口,那理所當然有公共處理核心業(yè)務(wù)的部分。

          TM對數(shù)據(jù)的存儲管理并不是依賴于接口,而是依賴于common.DB 結(jié)構(gòu)。根據(jù)配置文件中DB.driver 的值決定底層數(shù)據(jù)庫是mysql還是postgres兩種。

          再看這個DB結(jié)構(gòu),所以本質(zhì)上無論底層是哪種數(shù)據(jù)庫,都是直接依賴gorm來對數(shù)據(jù)進行操作的。


          接著,看下TM是如何通知各個RM進行commit或者rollback的?

          舉一個TCC模式的例子。


          TCC的兩個階段。

          • 階段一: try。嘗試執(zhí)行,調(diào)用各RM自定義的try行為,預(yù)留必要的業(yè)務(wù)資源。

          • 階段二:Confirm(階段一所有參與本次事務(wù)的try行為都成功)。調(diào)用各分支事務(wù)的Confirm方法,真正執(zhí)行業(yè)務(wù),并且只使用try階段預(yù)留的資源。

          • 階段二:Cancel(階段一任一參與本次事務(wù)的try行為失敗)。調(diào)用各分支事務(wù)的Cancel方法,釋放一階段try所預(yù)留的資源。


          從上面我們可以得知,TCC模式下,TM在第二階段要么通知各分支事務(wù)Confirm要么Cancel。


          在注冊各RM事務(wù)分支到TM的時候,最終TM會為每一個分布式事務(wù)的參與者(RM)生成兩條分支信息。


          就像這樣,


          對,就是把對應(yīng)的RM資源操作地址直接存入。


          當TM接收到commit或者rollback命令,在處理完自身邏輯(一般就是修改Gloable狀態(tài)),就需要開始處理每一個注冊進來的分支事務(wù)了,說白了就是需要調(diào)用各個分支事務(wù)對應(yīng)操作的接口。

          這里的t.getProcessor() 是需要根據(jù)當前事務(wù)的類型(TCC、SAGA、XA)獲取到對應(yīng)的處理器來進行邏輯的處理。

          當然,每個事務(wù)處理器只需要實現(xiàn)接口,

          真正調(diào)用RM資源服務(wù)地址的時候,分為http和grpc,這是由開發(fā)者決定的。

          在v1.6之前的版本,grpc的請求是很簡單粗暴解析地址方法然后連接的。

          現(xiàn)在為了支持那些采用gRPC Resolver 機制之上的一些微服務(wù)框架接入,做了一塊抽象。感興趣[1]可以看下,這里就不介紹了。


          SDK

          至于SDK,每一個事務(wù)模式都是獨立的,本質(zhì)上是沒有關(guān)聯(lián)的。比如下面我們啟動一個TCC分布式事務(wù)。這個分布式事務(wù)是由兩個服務(wù)組成,簡稱+30和-30的服務(wù)。


          從上面的調(diào)用中我們還是能還原出整體流程。


          • 調(diào)用TM,得到一個分布式id

          • 調(diào)用TccGlobalTransaction函數(shù)開啟分布式事務(wù)。

          • 調(diào)用TM prepare(這步只是為了查看第一步產(chǎn)生的那個分布式事務(wù)狀態(tài)是否處于prepare。這里沒看明白,此時還未注冊執(zhí)行分支,全局狀態(tài)不是應(yīng)該只會存在初始化狀態(tài)嗎)

          • 上一步?jīng)]問題,執(zhí)行傳入的閉包函數(shù),即CallBranch 函數(shù)里向TM注冊參與事務(wù)的TM分支。注冊完成后,開始第一階段調(diào)用各分支的try服務(wù)。

          • 各分支try服務(wù)調(diào)用結(jié)束,根據(jù)第一階段結(jié)果決定通知TM是submit還是abort。


          另外提一點,分布式事務(wù)常見的一些問題:比如空補償、重掛等問題。

          一般情況下,業(yè)務(wù)需要自行去處理這種場景,以免造成不可描述的錯誤。

          dtm里面提供了對應(yīng)子事務(wù)屏障方案。核心就在,


          其實就是利用數(shù)據(jù)庫的唯一索引機制,當然每個RM資源你都得新增一張表。


          上面提到,dtm的TM角色本質(zhì)上就是對應(yīng) seata 中的 TC,但是他們的處理模式是不同的。


          dtm中的TM會根據(jù)注冊時的各分支保存的地址,決定通過http還是rpc調(diào)用各RM操作,是由TM直接發(fā)起對RM的請求。


          seata-go的實現(xiàn)中,TC是不參與直接調(diào)用RM的。

          還記得上篇提到一個雙向流RPC接口(BranchCommunicate)。TC通過這個接口把對應(yīng)分支處理信息傳遞給RM管理器。

          然后由RM管理器根據(jù)事務(wù)類型選擇對應(yīng)的事務(wù)管理器進行處理,最終調(diào)用的是對應(yīng)事務(wù)類型管理器的BranchCommit方法。

          下面是一個TCC事務(wù)類型管理器的處。

          對應(yīng)的事務(wù)RM管理器是如何通知、處理各個RM資源的。

          原理就是我上篇提到的作者實現(xiàn)的一個全局事務(wù)代理模式,本質(zhì)上是利用go的反射實現(xiàn)的,感興趣的可以自己去扒下源碼,也可以看看作者對實現(xiàn)全局事務(wù)代理的介紹[2]


          總結(jié)

          這篇文章主要介紹了dtm實現(xiàn)的一些細節(jié),從這兩篇文章大體能看出實現(xiàn)上的部分區(qū)別,更多的細節(jié)還得靠自己去挖掘。


          最后再問幾個問題,

          • 日常開發(fā)中你們哪些場景是用到了分布式事務(wù)?用的是哪個框架還是自研的?

          • 或者說在分布式環(huán)境下,一致性的問題你們是如何解決的?


          相關(guān)

          • https://zhuanlan.zhihu.com/p/351391359

          • https://dtm.pub/protocol/support.html


          推薦閱讀


          福利

          我為大家整理了一份從入門到進階的Go學(xué)習(xí)資料禮包,包含學(xué)習(xí)建議:入門看什么,進階看什么。關(guān)注公眾號 「polarisxu」,回復(fù)?ebook?獲?。贿€可以回復(fù)「進群」,和數(shù)萬 Gopher 交流學(xué)習(xí)。

          瀏覽 80
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产做爰视频免费播放 | 俺来也网 | 成人大香蕉最新视频 | 一级免费黄色视频 | 伊人久久成人免费视频 |