<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 分布式事務(wù)最佳實(shí)踐

          共 3510字,需瀏覽 8分鐘

           ·

          2021-12-24 06:15

          背景

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

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

          • 跨行轉(zhuǎn)賬場景,數(shù)據(jù)不在一個數(shù)據(jù)庫,但需要保證余額扣減和余額增加要么同時成功,要么同時失敗
          • 發(fā)布文章后,更新文章總數(shù)等統(tǒng)計信息。其中發(fā)布文章和更新統(tǒng)計信息通常在不同的微服務(wù)中
          • 微服務(wù)化之后的訂單系統(tǒng)
          • 出行旅游需要在第三方系統(tǒng)同時定幾張票

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

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

          運(yùn)行一個例子

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

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

          • 配置 dtm
          MicroService:
          ????Driver:?'dtm-driver-gozero'?#?配置dtm使用go-zero的微服務(wù)協(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
          • 運(yùn)行一個 go-zero 的服務(wù)
          git?clone?github.com/yedf/dtmdriver-clients?&&?cd?dtmdriver-clients
          cd?gozero/trans?&&?go?run?trans.go
          • 用 go-zero 發(fā)起一個 dtm 的事務(wù)
          #?在dtmdriver-clients的目錄下
          cd?gozero/app?&&?go?run?main.go

          當(dāng)你在 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

          那就是事務(wù)正常完成了

          開發(fā)接入

          參考 yedf/dtmdriver-clients 的代碼

          //?下面這行導(dǎo)入gozero的dtm驅(qū)動
          import?_?"github.com/yedf/dtmdriver-gozero"

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

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

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

          ??//?使用dtmgrpc生成一個消息型分布式事務(wù)并提交
          ?gid?:=?dtmgrpc.MustGenGid(dtmServer)
          ?msg?:=?dtmgrpc.NewMsgGrpc(dtmServer,?gid).
          ????//?事務(wù)的第一步為調(diào)用trans.TransSvcClient.TransOut
          ????//?可以從trans.pb.go中找到上述方法對應(yīng)的Method名稱為"/trans.TransSvc/TransOut"
          ????//?dtm需要從dtm服務(wù)器調(diào)用該方法,所以不走強(qiáng)類型,而是走動態(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ā)接入的過程很少,前面的注釋已經(jīng)很清晰,就不再贅述了。

          注意事項(xiàng)

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

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

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

          dtm無需知道組成分布式事務(wù)的相關(guān)業(yè)務(wù)api的強(qiáng)類型,它是動態(tài)的調(diào)用這些api。

          grpc的調(diào)用,可以類比于HTTP的POST,其中:

          • c.BuildTarget() 產(chǎn)生的 target 類似于 URL 中的 Host
          • /trans.TransSvc/TransOut 相當(dāng)于 URL 中的 Path
          • &busi.BusiReq{Amount: 30, UserId: 1} 相當(dāng)于 Post 中 Body
          • pb.Response 相當(dāng)于 HTTP 請求的響應(yīng)

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

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

          更加完整的例子

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

          https://github.com/Mikaelemmmm/gozerodtm

          其他方式接入

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

          直連

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

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

          K8S

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

          K8S 中,將服務(wù)注冊到 K8S 中,是由 deployment.yaml 完成的,應(yīng)用內(nèi)部,不需要進(jìn)行注冊。

          直播分享預(yù)告

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

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

          小結(jié)

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

          • go-zero項(xiàng)目地址:https://github.com/zeromicro/go-zero
          • dtm項(xiàng)目地址:https://github.com/yedf/dtm

          歡迎大家使用 go-zerodtm,使用我們原生的 分布式事務(wù)的微服務(wù)解決方案,并 star 支持我們!



          推薦閱讀


          福利

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

          瀏覽 158
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <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>
                  韩国一区二区无码视频 | 米奇影院一区二区三区免费观看视频 | 国产精品久久久久久久久久梁医生 | 日日干天天射 | 国产精品一线 |