国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

go-zero學習 第六章 分布式事務dtm

這篇具有很好參考價值的文章主要介紹了go-zero學習 第六章 分布式事務dtm。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

1 參考文檔

  1. Go開源說第十七期 分布式事務DTM
  2. DTM開源項目文檔:官方文檔
  3. 分布式事務解決方案:7種常見解決方案匯總
  • msg:二階段消息,適合不需要回滾的全局事務。
  • saga:適合需要支持回滾的全局事務。
  • tcc:適合一致性要求較高的全局事務。
  • xa:適合性能要求不高,沒有行鎖爭搶的全局事務。

2 官方示例

參考:https://github.com/dtm-labs/dtm/blob/main/helper/README-cn.md

以下步驟均是按參考實操的。

  1. 運行dtm服務器(可以觀察事務執(zhí)行情況)

運行示例前,必須首先運行dtm服務器。

git clone https://github.com/dtm-labs/dtm && cd dtm
go mod tidy
go run main.go
  1. 啟動并運行一個saga示例

下面運行一個類似跨行轉賬的示例,包括兩個事務分支:資金轉出(TransOut)、資金轉入(TransIn)。DTM保證TransInTransOut要么全部成功,要么全部回滾,保證最終金額的正確性。

git clone https://github.com/dtm-labs/dtmcli-go-sample && cd dtmcli-go-sample
go run main.go
  1. dtmcli-go-sample 中的具體代碼
package main

import (
	"fmt"
	"log"
	"time"

	"github.com/dtm-labs/dtmcli"
	"github.com/gin-gonic/gin"
)

// 事務參與者的服務地址
const qsBusiAPI = "/api/busi_start"
const qsBusiPort = 8082

var qsBusi = fmt.Sprintf("http://localhost:%d%s", qsBusiPort, qsBusiAPI)

func main() {
	QsStartSvr()
	_ = QsFireRequest()
	select {}
}

// QsStartSvr quick start: start server
func QsStartSvr() {
	app := gin.New()
	qsAddRoute(app)
	log.Printf("quick start examples listening at %d", qsBusiPort)
	go func() {
		_ = app.Run(fmt.Sprintf(":%d", qsBusiPort))
	}()
	time.Sleep(100 * time.Millisecond)
}

func qsAddRoute(app *gin.Engine) {
	app.POST(qsBusiAPI+"/TransIn", func(c *gin.Context) {
		log.Printf("TransIn")
		c.JSON(200, "")
		// c.JSON(409, "") // Status 409 for Failure. Won't be retried
	})
	app.POST(qsBusiAPI+"/TransInCompensate", func(c *gin.Context) {
		log.Printf("TransInCompensate")
		c.JSON(200, "")
	})
	app.POST(qsBusiAPI+"/TransOut", func(c *gin.Context) {
		log.Printf("TransOut")
		c.JSON(200, "")
	})
	app.POST(qsBusiAPI+"/TransOutCompensate", func(c *gin.Context) {
		log.Printf("TransOutCompensate")
		c.JSON(200, "")
	})
}

const dtmServer = "http://localhost:36789/api/dtmsvr"

// QsFireRequest quick start: fire request
func QsFireRequest() string {
	req := &gin.H{"amount": 30} // 微服務的載荷
	// DtmServer為DTM服務的地址
	saga := dtmcli.NewSaga(dtmServer, dtmcli.MustGenGid(dtmServer)).
		// 添加一個TransOut的子事務,正向操作為url: qsBusi+"/TransOut", 逆向操作為url: qsBusi+"/TransOutCompensate"
		Add(qsBusi+"/TransOut", qsBusi+"/TransOutCompensate", req).
		// 添加一個TransIn的子事務,正向操作為url: qsBusi+"/TransOut", 逆向操作為url: qsBusi+"/TransInCompensate"
		Add(qsBusi+"/TransIn", qsBusi+"/TransInCompensate", req)
	// 提交saga事務,dtm會完成所有的子事務/回滾所有的子事務
	err := saga.Submit()

	if err != nil {
		panic(err)
	}
	log.Printf("transaction: %s submitted", saga.Gid)
	return saga.Gid
}
  1. 失敗情況
    在實際的業(yè)務中,子事務可能出現失敗,例如轉入的子賬號被凍結導致轉賬失敗。我們對業(yè)務代碼進行修改,讓TransIn的正向操作失敗,然后看看結果:
	app.POST(qsBusiAPI+"/TransIn", func(c *gin.Context) {
		logger.Infof("TransIn")
		c.JSON(409, "") // Status 409 表示失敗,不再重試,直接回滾
	})

在轉入操作失敗的情況下,TransInTransOut的補償操作被執(zhí)行,保證了最終的余額和轉賬前是一樣的。

3 go-zero使用dtm參考代碼

3.1 go-zero支持dtm 代碼操作步驟

參考:go-zero支持dtm:官方講解+代碼

注意:這里只是從調用方角度展示了如何使用dtm的代碼,而關于被調用方的代碼缺失,需要結合3.2 gozerodtm 代碼操作步驟。

  1. 啟動Etcd,查看所有key命令:etcdctl.exe get --prefix ""
  2. 把dtm clone下來
  3. 找到dtm項目根文件夾下的conf.sample.yml,復制一份名稱改為conf.yml
  4. conf.yml中的下面這段注釋放開:
MicroService: # gRPC/HTTP based microservice config
   Driver: 'dtm-driver-gozero' # name of the driver to handle register/discover
   Target: 'etcd://localhost:2379/dtmservice' # register dtm server to this url
   EndPoint: 'localhost:36790'
  • MicroService:這個不要動,這個代表要對把dtm注冊到那個微服務服務集群里面去,使微服務集群內部服務可以通過grpc直接跟dtm交互
  • Driver'dtm-driver-gozero', 使用go-zero的注冊服務發(fā)現驅動,支持go-zero
  • Target: 'etcd://localhost:2379/dtmservice'將當前dtmserver直接注冊到微服務所在的etcd集群中,如果go-zero作為微服務使用的話,就可以直接通過etcd拿到dtmserver grpc鏈接,直接就可以跟dtm server交互了。
  • EndPoint: 'localhost:36790' , 代表的是dtmserver的連接地址+端口 , 集群中的微服務可以直接通過etcd獲得此地址跟dtm交互了,如果你自己去改了dtm源碼grpc端口,記得這里要改下端口。
  1. 啟動dtm
# 前提:配置好conf.yml
go run main.go -c conf.yml

如果是用Goland啟動,則需要將 -c conf.yml作為參數填寫到Program arguments中。

  1. 運行一個go-zero的服務
git clone https://github.com/dtm-labs/dtmdriver-clients && cd dtmdriver-clients
cd gozero/trans && go run trans.go
  1. 發(fā)起一個go-zero使用dtm的事務
# 在dtmdriver-clients的目錄下
cd gozero/app && go run main.go
  1. trans的日志中看到記錄信息,就是事務正常完成了
2023/07/24 21:45:47 transfer out 30 cents from 1
2023/07/24 21:45:47 transfer in 30 cents to 2   
2023/07/24 21:45:47 transfer out 30 cents from 1
2023/07/24 21:45:47 transfer out 30 cents from 1

※3.2 gozerodtm 代碼操作步驟

參考:gozerodtm:Mikaelemmmm代碼

項目介紹:

  • order-apihttp服務入口。
  • order-srv是訂單的rpc服務,與dtm-gozero-order數據庫中order表交互。
  • stock-srv是庫存的rpc服務,與dtm-gozero-stock數據庫中stock表交互。

整體流程:
http調用order-api中立即下單接口,然后order-api立即下單接口會去調用order-srv創(chuàng)建訂單并且調用stock-srv扣減庫存,因為order-srvstock-srv是2個獨立grpc服務,所以使用dtm來做分布式事務協調。

前5步與3.1完全一致。

  1. 創(chuàng)建數據庫表
    在項目的datasql目錄下分別有:order-srv服務的dtm-gozero-order.sql、stock-srv服務的dtm-gozero-stock.sql,在數據庫按照創(chuàng)建兩個數據庫并執(zhí)行相關sql。
  2. 修改數據庫連接配置
    分別修改 order-srvstock-srv服務的yaml中的數據庫連接配置。
  3. 修改啟動類讀取配置文件的路徑
    分別修改order-api、order-srvstock-srv中讀取yaml配置的路徑。
  4. 啟動服務
    依次啟動order-srv、stock-srv、order-api服務
  5. 請求測試
    使用POSTMAN測試:
    請求地址:http://localhost:8889/order/quickCreate
    請求方式:POST
    數據格式:JSON
    請求數據:{"userId":2,"goodsId":1,"num":20}
  6. 測試結果
    HTTP請求響應成功,狀態(tài)是200,但是查看DTM服務發(fā)現,操作失敗,且數據庫中數據未改變。
    原因排查:
    依次查看order-api、order-srv、stock-srv服務后,發(fā)現在order-srv服務有報錯,主要報錯信息:
{"level":"error","ts":"2023-07-25T14:08:24.891+0800","caller":"dtmimp/utils.go:207","msg":"used: 0 ms exec error: Error 1146: Table 'dtm_barrier.barrier' doesn't exist for insert i
gnore into dtm_barrier.barrier(trans_type, gid, branch_id, op, barrier_id, reason) values(?,?,?,?,?,?)

推斷是缺少dtm_barrier數據庫以及barrier數據表。

  1. 創(chuàng)建dtm_barrier數據庫以及barrier數據表
/*
 Navicat Premium Data Transfer

 Source Server         : 本機
 Source Server Type    : MySQL
 Source Server Version : 50737
 Source Host           : 127.0.0.1:3357
 Source Schema         : dtm_barrier

 Target Server Type    : MySQL
 Target Server Version : 50737
 File Encoding         : 65001

 Date: 25/07/2023 14:06:43
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for barrier
-- ----------------------------
DROP TABLE IF EXISTS `barrier`;
CREATE TABLE `barrier`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `trans_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `gid` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `branch_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `op` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `barrier_id` bigint(20) NULL DEFAULT NULL,
  `reason` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `create_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0),
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'dtm子屏障數據表' ROW_FORMAT = DYNAMIC;

SET FOREIGN_KEY_CHECKS = 1;
  1. 重新請求測試
    HTTP請求響應成功,狀態(tài)是200,DTM服務中狀態(tài)顯示操作成功,且數據庫中數據改變。

4 注意事項

3.1 go-zero支持dtm 代碼操作步驟※3.2 gozerodtm 代碼操作步驟有一些操作注意事項。

重點是子事務如何處理 回滾、補償等操作,這一塊需要特別留意。

4.1 grpc接口地址

在找grpc訪問的方法路徑時候,是在***.pb.go的文件中找該方法invoke的路徑。
原因:當proto文件方法名字都是大寫,這2者都一樣如果proto中方法名字小寫的,invoke中跟他的方法名就不一樣了
go-zero學習 第六章 分布式事務dtm,go-zero,golang
仔細觀察發(fā)現兩個路徑有大小寫之分!
go-zero學習 第六章 分布式事務dtm,go-zero,golang

※4.2 動態(tài)調用過程

在go-zero使用dtm的分布式事務時,許多的調用是從dtm服務器發(fā)起的,例如TCC的Confirm/Cancel,SAGA/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})

4.3 dtm的回滾補償

在使用dtm的grpc時候,當我們使用saga、tcc等如果第一步嘗試或者執(zhí)行失敗了,是希望它能執(zhí)行后面的rollback的,在grpc中的服務如果發(fā)生錯誤了,必須返回 : status.Error(codes.Aborted, dtmcli.ResultFailure) , 返回其他錯誤,不會執(zhí)行你的rollback操作,dtm會一直重試,如下圖:
go-zero學習 第六章 分布式事務dtm,go-zero,golang

4.4 barrier的空補償、懸掛等

這一步需要創(chuàng)建dtm_barrier數據庫以及barrier數據表。這個其實就是為我們的業(yè)務服務做了一個檢查,防止空補償,具體可以看barrier.Call中源碼,沒幾行代碼可以看懂的。

每個與db交互的服務只要用到了barrier,都需要這個。

4.5 barrier在rpc中本地事務

在rpc的業(yè)務中,如果使用了barrier的話,那么在model中與db交互時候必須要用事務,并且一定要跟barrier用同一個事務。
logic:
go-zero學習 第六章 分布式事務dtm,go-zero,golang
model:
go-zero學習 第六章 分布式事務dtm,go-zero,golang文章來源地址http://www.zghlxwxcb.cn/news/detail-605999.html

到了這里,關于go-zero學習 第六章 分布式事務dtm的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • go-zero數據庫連接池 database/sql 源碼學習

    database/sql 中接口的層級關系 https://draveness.me/golang/docs/part4-advanced/ch09-stdlib/golang-database-sql/ database/sql源碼地址 : https://github.com/golang/go/tree/release-branch.go1.17/src/database/sql go-zero數據庫連接池源碼地址 https://github.com/zeromicro/go-zero/blob/master/core/stores/sqlx/sqlmanager.go 滑動驗證頁面 go

    2024年02月06日
    瀏覽(18)
  • 【go零基礎】go-zero從零基礎學習到實戰(zhàn)教程 - 2項目初始化

    【go零基礎】go-zero從零基礎學習到實戰(zhàn)教程 - 2項目初始化

    到項目初始化過程了,這邊的項目設計完全按照作者自己的喜好來進行定義和設置的,所以各位完全可以按照自己的偏好自喜設置哈。 首先是創(chuàng)建一個工作文件夾哈。 別問為啥不直接quickstart,因為quickstart生成的api名字是greet,改起來很麻煩(頭禿)。 注1: go-zero-demo是我隨便

    2024年04月26日
    瀏覽(37)
  • 【go-zero】docker鏡像直接部署go-zero的API與RPC服務 如何實現注冊發(fā)現?docker network 實現 go-zero 注冊發(fā)現

    【go-zero】docker鏡像直接部署go-zero的API與RPC服務 如何實現注冊發(fā)現?docker network 實現 go-zero 注冊發(fā)現

    使用docker直接部署go-zero微服務會發(fā)現API無法找到RPC服務 用docker直接部署 我們會發(fā)現API無法注冊發(fā)現RPC服務 原因是我們缺少了docker的network網橋 RPC服務運行正常 API服務啟動,通過docker logs 查看日志還是未發(fā)現RPC API的yaml配置 RPC服務的IP是 127.0.0.1 與對應的端口 下圖為改成了定

    2024年02月13日
    瀏覽(28)
  • 【go-zero】go-zero阿里云oss 前端上傳文件到go-zero API服務 并在k8s pod中創(chuàng)建文件 并推送到阿里云oss 最佳實踐

    問題:在本地通過上傳文件,然后將文件推送到aliyun的oss中,是沒問題的 但是部署到了k8s中,則出現了問題,一直報錯沒有創(chuàng)建的權限 思路:開始認為應該將該文件掛載到configmap中,然后通過這種方式修改了deployment和dockerfile。最終發(fā)現應該是go的創(chuàng)建文件路徑方式搞錯了,

    2024年02月13日
    瀏覽(29)
  • LLM-分布式訓練工具(一):DeepSpeed【微軟】【大模型分布式訓練工具,實現ZeRO并行訓練算法】【zero3配置將模型參數切分后分配到不同的顯卡中,突破單張顯卡容量不足以加載模型參數的限制】

    DeepSpeed是微軟推出的大規(guī)模模型分布式訓練的工具,主要實現了ZeRO并行訓練算法。 原始文檔鏈接: DeepSpeed Optimizer state partitioning (ZeRO stage 1) Gradient partitioning (ZeRO stage 2) Parameter partitioning (ZeRO stage 3) Custom mixed precision training handling A range of fast CUDA-extension-based optimizers ZeRO-Offlo

    2024年02月16日
    瀏覽(23)
  • go-zero系列:接入Prometheus

    go-zero系列:接入Prometheus

    參考文檔:https://zhuanlan.zhihu.com/p/463418864 https://prometheus.io/download/ 進入下載文件夾,比如prometheus-2.44.0.windows-amd64。 然后雙擊Prometheus.exe啟動軟件。 啟動后,可以訪問 http://127.0.0.1:9090/。就能查看Prometheus后臺。 然后重啟go-zero項目,能看到輸出日志:Starting prometheus agent at 0.0.

    2024年02月16日
    瀏覽(19)
  • go-zero的服務發(fā)現源碼閱讀

    go-zero的服務發(fā)現源碼閱讀

    服務發(fā)現原理與grpc源碼解析_wangxiaoangg的博客-CSDN博客 ? go-zero rpc demo官方文檔:rpc編寫與調用 | go-zero 目錄 一 服務注冊 1.?創(chuàng)建rpc服務 2. 啟動rpc服務 3.?registerEtcd做了什么 4.?discov.NewPublisher 服務發(fā)布者 二 服務發(fā)現 1.定義注冊resolver 2.解析etcd地址創(chuàng)建鏈接 3.update方法 在看rp

    2024年02月06日
    瀏覽(16)
  • go-zero 開發(fā)之安裝 etcd

    本文只涉及 Linux 上的安裝。 二進制安裝 下載二進制安裝包 下載地址示例: 解壓二進制安裝包 刪除二進制安裝包 版本檢查 啟動 etcd 往 etcd 寫讀數據 Docker 安裝 etcd 主要使用 Google 容器注冊表(gcr.io)下的 gcr.io/etcd-development/etcd 倉庫來存儲其容器鏡像。作為次要選項,它還使

    2024年02月04日
    瀏覽(18)
  • go-zero微服務實戰(zhàn)——服務構建

    go-zero微服務實戰(zhàn)——服務構建

    接上一節(jié)go-zero微服務實戰(zhàn)——基本環(huán)境搭建。搭建好了微服務的基本環(huán)境,開始構建整個微服務體系了,將其他服務也搭建起來。 order的目錄結構,如下 根目錄 api服務 rpc服務 自定義邏輯層logic 自定義參數層models 自定義工具層util api服務和rpc服務都是基于goctl一鍵生成的,當

    2024年02月14日
    瀏覽(24)
  • 使用go-zero快速構建微服務

    使用go-zero快速構建微服務

    本文是對 使用go-zero快速構建微服務 [1] 的親手實踐 編寫API Gateway代碼 mkdir api goctl api -o api/bookstore.api cd api goctl api go -api bookstore.api -dir . go run bookstore.go -f etc/bookstore-api.yaml 啟動API Gateway服務,默認偵聽在8888端口 因為默認生成的 api/etc/bookstore-api.yml 為: 按提示下載,再次運行

    2024年02月13日
    瀏覽(25)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包