<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-zero 分布式事務最佳實踐

          共 3418字,需瀏覽 7分鐘

           ·

          2021-12-29 13:56

          隨著業(yè)務的快速發(fā)展、業(yè)務復雜度越來越高,微服務作為最佳解決方案之一,它解耦服務,降低復雜度,增加可維護性的同時,也帶來一部分新問題。

          當我們需要跨服務保證數(shù)據(jù)一致性時,原先的數(shù)據(jù)庫事務力不從心,無法將跨庫、跨服務的多個操作放在一個事務中。這樣的應用場景非常多,我們可以列舉出很多:

          • 跨行轉賬場景,數(shù)據(jù)不在一個數(shù)據(jù)庫,但需要保證余額扣減和余額增加要么同時成功,要么同時失敗

          • 發(fā)布文章后,更新文章總數(shù)等統(tǒng)計信息。其中發(fā)布文章和更新統(tǒng)計信息通常在不同的微服務中

          • 微服務化之后的訂單系統(tǒng)

          • 出行旅游需要在第三方系統(tǒng)同時定幾張票

          面對這些本地事務無法解決的場景,我們需要分布式事務的解決方案,保證跨服務、跨數(shù)據(jù)庫更新數(shù)據(jù)的一致性。

          go-zero 與 dtm 強強聯(lián)合,推出了在 go-zero 中無縫接入 dtm 的極簡方案,讓分布式事務的使用從未如此簡單。

          # 運行一個例子

          我們來看一個可運行的例子,然后再看如何自己開發(fā)完成一個完整的分布式事務

          下面以 etcd 作為注冊服務中心,可以按照如下步驟運行一個 go-zero 的示例:

          • 配置 dtm

          MicroService:
          ????Driver:?'dtm-driver-gozero'?#?配置dtm使用go-zero的微服務協(xié)議
          ????Target:?'etcd://localhost:2379/dtmservice'?#?把dtm注冊到etcd的這個地址
          ????EndPoint:?'localhost:36790'?#?dtm的本地地址
          • 啟動 etcd

          #?前提:已安裝etcd
          etcd
          • 啟動 dtm

          #?前提:已配置好dtm的數(shù)據(jù)庫鏈接
          go?run?app/main.go?dev
          • 運行一個 go-zero 的服務

          git?clone?github.com/yedf/dtmdriver-clients?&&?cd?dtmdriver-clients
          cd?gozero/trans?&&?go?run?trans.go
          • 用 go-zero 發(fā)起一個 dtm 的事務

          #?在dtmdriver-clients的目錄下
          cd?gozero/app?&&?go?run?main.go

          當你在 trans 的日志中看到

          2021/12/03?15:44:05?transfer?out?30?cents?from?1
          2021/12/03?15:44:05?transfer?in?30?cents?to?2
          2021/12/03?15:44:05?transfer?out?30?cents?from?1
          2021/12/03?15:44:05?transfer?out?30?cents?from?1

          那就是事務正常完成了

          # 開發(fā)接入

          參考 yedf/dtmdriver-clients 的代碼

          //?下面這行導入gozero的dtm驅動
          import?_?"github.com/yedf/dtmdriver-gozero"

          //?使用dtm的客戶端dtmgrpc之前,需要執(zhí)行下面這行調用,告知dtmgrpc使用gozero的驅動來如何處理gozero的url
          err?:=?dtmdriver.Use("dtm-driver-gozero")
          //?check?err

          //?dtm已經通過前面的配置,注冊到下面這個地址,因此在dtmgrpc中使用該地址
          var?dtmServer?=?"etcd://localhost:2379/dtmservice"

          //?下面從配置文件中Load配置,然后通過BuildTarget獲得業(yè)務服務的地址
          var?c?zrpc.RpcClientConf
          conf.MustLoad(*configFile,?&c)
          busiServer,?err?:=?c.BuildTarget()

          ??//?使用dtmgrpc生成一個消息型分布式事務并提交
          ?gid?:=?dtmgrpc.MustGenGid(dtmServer)
          ?msg?:=?dtmgrpc.NewMsgGrpc(dtmServer,?gid).
          ????//?事務的第一步為調用trans.TransSvcClient.TransOut
          ????//?可以從trans.pb.go中找到上述方法對應的Method名稱為"/trans.TransSvc/TransOut"
          ????//?dtm需要從dtm服務器調用該方法,所以不走強類型,而是走動態(tài)的url:?busiServer+"/trans.TransSvc/TransOut"
          ??Add(busiServer+"/trans.TransSvc/TransOut",?&busi.BusiReq{Amount:?30,?UserId:?1}).
          ??Add(busiServer+"/trans.TransSvc/TransIn",?&busi.BusiReq{Amount:?30,?UserId:?2})
          ?err?:=?msg.Submit()

          整個開發(fā)接入的過程很少,前面的注釋已經很清晰,就不再贅述了。

          ?注意事項

          在開發(fā)接入的過程中,去找 *.pb.go 的文件中的 grpc 訪問的方法路徑時候,一定要找 invoke 的路徑

          img
          img

          # 深入理解動態(tài)調用

          在 go-zero 使用 dtm 的分布式事務時,許多的調用是從 dtm 服務器發(fā)起的,例如 TCC 的 Confirm/CancelSAGA/MSG 的所有調用。

          dtm無需知道組成分布式事務的相關業(yè)務api的強類型,它是動態(tài)的調用這些api。

          grpc的調用,可以類比于HTTP的POST,其中:

          • c.BuildTarget() 產生的 target 類似于 URL 中的 Host

          • /trans.TransSvc/TransOut 相當于 URL 中的 Path

          • &busi.BusiReq{Amount: 30, UserId: 1} 相當于 Post 中 Body

          • pb.Response 相當于 HTTP 請求的響應

          通過下面這部分代碼,dtm 就拿到了完整信息,就能夠發(fā)起完整的調用了

          Add(busiServer+"/trans.TransSvc/TransOut",?&busi.BusiReq{Amount:?30,?UserId:?1})

          # 更加完整的例子

          熱心的社區(qū)同學 Mikael 幫忙寫了一個內容更加豐富的例子,結合實際應用和子事務屏障,完整的演示了一個線上實際運行的分布式事務,有興趣的同學可以參考:

          https://github.com/Mikaelemmmm/gozerodtm

          # 其他方式接入

          go-zero 的微服務還有非 etcd 的其他方式,我們依次說明他們的接入方式

          ?直連

          對于直連這種方式,您只需要在上面 dtmetcd 配置基礎上,將 Target 設置為空字符串即可。

          直連的情況,不需要將 dtm 注冊到注冊中心。

          ?K8S

          對于 K8S 這種方式,您只需要在上面 dtmetcd 配置基礎上,將 Target 設置為空字符串即可。

          K8S 中,將服務注冊到 K8S 中,是由 deployment.yaml 完成的,應用內部,不需要進行注冊。

          # 直播分享預告

          go-zero 作者和我(dtm 作者)將在12月22日晚21點,在 Go 夜讀,聯(lián)合做一場《go-zero 的分布式事務實踐》的直播分享,將會帶來更多更深入的討論。歡迎大家屆時參加。

          直播地址為:https://live.bilibili.com/11171965

          # 小結

          這一次 go-zerodtm 的合作,在 go 生態(tài)中,打造了首個原生支持分布式事務的微服務解決方案,意義重大。

          • go-zero項目地址:https://github.com/zeromicro/go-zero

          • dtm項目地址:https://github.com/yedf/dtm

          歡迎大家使用 go-zerodtm,使用我們原生的 分布式事務的微服務解決方案

          ? ?


          喜歡明哥文章的同學
          歡迎長按下圖訂閱!

          ???

          瀏覽 92
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

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

          手機掃一掃分享

          分享
          舉報
          <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>
                  久久久久久蜜桃 | 精品婷婷 | 成人污污 | 天天日日夜夜a v | 日日干天天干视频 |