1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        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í)行下面這行調(diào)用,告知dtmgrpc使用gozero的驅動來如何處理gozero的url
        err?:=?dtmdriver.Use("dtm-driver-gozero")
        //?check?err

        //?dtm已經(jīng)通過前面的配置,注冊到下面這個地址,因此在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).
        ????//?事務的第一步為調(diào)用trans.TransSvcClient.TransOut
        ????//?可以從trans.pb.go中找到上述方法對應的Method名稱為"/trans.TransSvc/TransOut"
        ????//?dtm需要從dtm服務器調(diào)用該方法,所以不走強類型,而是走動態(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)很清晰,就不再贅述了。

        ?注意事項

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

        img
        img

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

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

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

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

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

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

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

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

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

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

        # 更加完整的例子

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

        https://github.com/Mikaelemmmm/gozerodtm

        # 其他方式接入

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

        ?直連

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

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

        ?K8S

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

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

        # 直播分享預告

        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
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

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

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            摸少妇的奶她呻吟不断爽视频 | 日本老妇乱伦 | 九九热久久久99国产盗摄蜜臀 | 天天射天天干 | 美女乱淫aaaa高清视频 | 无打码成人影片在线观看 | 艳女十八式淫在线观看 | 极品乱人伦 | 做爱视频网站成人网站 | 91制片厂毛片操逼视频 |