go-zero 實戰(5)

引入Prometheus

用 Prometheus 監控應用

1. 用 docker 啟動 Prometheus

編輯配置位置,我將 prometheus.yaml 和 targets.json 文件放在了 /opt/prometheus/conf目錄下

prometheus.yaml

global:scrape_interval: 15s # 抓取間隔evaluation_interval: 15s # 評估間隔scrape_configs:- job_name: 'file_ds'file_sd_configs:- files:- 'targets.json'

由于 prometheus.yaml 文件中,用到了 targets.json 文件,因此,引入 targets.json文件

targets.json

[{"targets":["192.168.10.20:9081"],"labels": {"job": "user-api","app": "user-api","env": "test","instance": "192.168.10.20:8888"}    }
]

我的應用是啟動在 宿主機的 8888 端口,因此,我這里寫了宿主機的 ip 和端口。
上面的 9081 端口,可以隨便寫。但是要與應用中的配置一致,看后面配置。

docker run -d --name prometheus --dns=192.168.10.20 -p 9090:9090  -v /opt/prometheus/conf/prometheus.yaml:/etc/prometheus/prometheus.yml  -v /opt/prometheus/conf/targets.json:/etc/prometheus/targets.json quay.io/prometheus/prometheusdocker run -d --name prometheus --network host   -v /opt/prometheus/conf/prometheus.yaml:/etc/prometheus/prometheus.yml  -v /opt/prometheus/conf/targets.json:/etc/prometheus/targets.json quay.io/prometheus/prometheus

下面兩條命令都可以啟動 Prometheus。

2. 啟動應用

修改應用的配置文件 userapi/etc/userapi-api.yaml 文件。

在這里插入圖片描述
增加了 Prometheus 配置,端口號與 targets.json 文件中的 targets 條目標識的端口號保持一致。

3.測試

訪問 http://192.168.10.20:9090/targets?search=
在這里插入圖片描述
這樣可以看到 Prometheus 監控了應用。

引入 jaeger

jaeger 是一個用于鏈路追蹤的中間件。

1. docker 啟動 jaeger

docker run -d -e COLLECTOR_ZIPKIN_HTTP_PORT=9411 -p 5775:5775/udp -p 6831:6831/udp -p 6832:6832/udp -p 5778:5778  -p 16686:16686 -p 14268:14268  -p 14269:14269   -p 9411:9411 jaegertracing/all-in-one:latest

這樣啟動的 jaeger,數據默認是放在內存中的。可以根據直接的需求,選擇將數據放在 elasticsearch或其它存儲中。

  • 其中 16686 是 ui 端口,直接訪問 http://localhost:16686 便可以進入到 ui 界面
    在這里插入圖片描述

2. 修改 userapi/etc/userapi-api.yaml 文件

在配置文件中加入如下配置:

Telemetry:Name: user-apiEndpoint: http://localhost:14268/api/tracesSampler: 1.0Batcher: jaeger

3. 測試

啟動 userapi 應用,用postman 訪問接口。
在這里插入圖片描述
這樣就可以在 jaeger 的 ui 上看到訪問的接口。

分布式事務

分布式事務也是微服務架構中必不可少的一部分。go-zero 使用了dtm的方案來解決分布式事務問題。

1. 引入 DTM

官網鏈接

1. github clone 項目

項目地址:https://github.com/dtm-labs/dtm.git

2. 進入項目

創建 conf.yml 配置文件,加入如下配置:

MicroService: # gRPC/HTTP based microservice configDriver: 'dtm-driver-gozero' # name of the driver to handle register/discoverTarget: 'etcd://localhost:2379/dtmservice' # register dtm server to this urlEndPoint: 'localhost:36790'

3. 啟動dtm

從源碼處啟動 dtm

go run main.go -c conf.yml 

在這里插入圖片描述

2. 創建表

在當前使用的微服務對應的數據中創建表。我們曾在 go-zero實戰(2)中創建過zero-mall數據庫。同樣在該數據庫創建 barrier表。

create table if not exists barrier(id bigint(22) primary key auto_increment,trans_type varchar(45),gid varchar(128),branch_id varchar(128),op varchar(45),barrier_id varchar(45),reason varchar(45),create_time datetime default now(),update_time datetime default now(),key(create_time),key(update_time),unique key(gid, branch_id, op, barrier_id)
);

3. 創建積分服務

1. 在 zero_mall 數據庫中 創建 user_score 表

create table user_score(id bigint(0) not null auto_increment,user_id bigint(0) not null,score int(0) not null,primary key(id) using btree
);

2. 創建 user_score.proto 文件

syntax = "proto3";package userscore;option go_package = "./score";message UserScoreRequest {int64 userId = 1;int32 score = 2;
}message UserScoreResponse {int64 userId = 1;int32 score = 2;
}service UserScore {rpc saveScore(UserScoreRequest) returns(UserScoreResponse);rpc saveScoreCallback(UserScoreRequest) returns(UserScoreResponse);
}

為了使用 dmt 實現的分布式事務,saveScore 方法,需要有一個相應的 Callback 方法。為了在發生異常回滾時,執行該方法。

3. 生成代碼

goctl rpc protoc user_score.proto --go_out=./types --go-grpc_out=./types --zrpc_out=.

4. 整理代碼

  1. 將 生成的 user_score.pb.go 文件和 user_score_grpc.pb.go 文件放入 rpc-common 工程的score目錄下。
  2. 將 userscore.go 文件放入 rpc-common 工程的 userscore 目錄下。
  3. 在user-score 創建 go.mod 文件,如下:
    module user-scorego 1.22.2
    
  4. 在 mall 工程下,執行如下命令:
    go work use user-score  # 加入 workspace
    go mod tidy             # 下載依賴
    
  5. 在 user-score 創建 database 目錄,并增加 sqlx.go 文件,參考 go-zero 實戰(3)
  6. 將user 微服務 user/internal 目錄下的 dao、repo、model三個目錄復制一份到 user-score 微服務的 user-score/internal 目錄下并做相應的命名修改。
  7. 修改 user-score/etc/userscore.yaml 文件
    Name: score.rpc
    ListenOn: 127.0.0.1:8081
    Etcd:Hosts:- 127.0.0.1:2379Key: score.rpc
    Mysql:Datasource: root:thinker@tcp(127.0.0.1:3306)/zero_mall?charset=utf8mb4&parseTime=True&loc=Asia%2FShanghaiCacheRedis:- Host: 127.0.0.1:6379Pass: thinkerType: node
    
  8. 修改 user-score/internal/svc/servicecontext.go 文件,加入 UserScoreRepo
  9. 修改生成的 savescorelogic.go 和 savescorecallbacklogic.go 文件

到此,積分服務創建完成。

4. 在 userapi 中調用積分服務

1. 修改 userapi/etc/userapi-api.yaml 文件

加入 user-score 微服務的 rpc 配置

UserScoreRpc:Etcd:Hosts:- 127.0.0.1:2379Key: score.rpc

2. 修改 userapi/intrenal/config/config.go 文件

在這里加入 user-score 微服務的 rpc。
在這里插入圖片描述

3. 在 userapi/internal/svc/servicecontext.go 文件為上一步增加的變量賦值

在這里插入圖片描述

因為userapi 是作為 rpc 客戶端,而 user-score 微服務是 rpc 服務端。并且這兩個服務都會用到公共的部分,于是,將公共部分抽取到 rpc-common 下。這樣,userapi 微服務不會用到 user-score 微服務下的代碼。

4. 修改 userapi/internal/logic/userapilogic.go 文件

我們修改了 Register 接口,增加調用 user-score 微服務的代碼。

到此,算是正常走通了。在 userapi 微服務下,注冊功能實現時,同時調用了 user服務和 user-score 服務。

5. 測試

在這里插入圖片描述

代碼,這部分代碼提交到了 score 分支。

6. 使用 DTM

在上面的注冊功能里,從userapi 遠程調用了 user 和 user-score 兩個服務。試想,如果有一個微服務調用錯誤,顯然不會影響到另一個。我們引入分布式事務,就為了解決在注冊成功后,用戶能夠增加積分。如果積分增加失敗的情況下,也要保證注冊不成功。

1. 在項目中導入 dtm

分別在 /mall/userapi、/mall/user、/mall/user-score 下執行命令:

go get github.com/dtm-labs/dtm

2. 項目中加入dtm 驅動

  1. 修改 userapi/internal/logic/userapilogic.go 文件
    加入驅動

    	_ "github.com/dtm-labs/dtmdriver-gozero"// 這里的地址在文章 分布式事務 1.2 這個步驟,修改配置文件時候,指定的地址// 先上看 1.2 步驟可以找到var dtmServer = "etcd://localhost:2379/dtmservice" 
    

3. 修改 userapi/internal/userapilogic.go 文件

修改 Register 方法的邏輯,引入 dtm

func (l *UserLogic) Register(req *types.Request) (resp *types.Response, err error) {gid := dtmgrpc.MustGenGid(dtmServer)sagaGrpc := dtmgrpc.NewSagaGrpc(dtmServer, gid)userServer, err := l.svcCtx.Config.UserRpc.BuildTarget()if err != nil {return nil, err}userScoreServer, err := l.svcCtx.Config.UserScoreRpc.BuildTarget()if err != nil {return nil, err}userReq := &user.UserRequest{Id:     req.Id,Name:   req.Name,Gender: req.Gender,}// call save methodsagaGrpc.Add(userServer+"/user.User/save", userServer+"/user.User/saveCallback", userReq)// 這個地方,應該是傳入一個User,因為遠程調用拿不到返回值。暫且先寫死,為了測試效果。userScoreReq := &score.UserScoreRequest{UserId: req.Id,Score:  10,}sagaGrpc.Add(userScoreServer+"/userscore.UserScore/saveScore", userScoreServer+"/userscore.UserScore/saveScoreCallback", userScoreReq)sagaGrpc.WaitResult = trueerr = sagaGrpc.Submit()if err != nil {fmt.Println("---------------------------")fmt.Println(err)return nil, err}//fmt.Sprintf("register add score %d \n", userScore.Score)return &types.Response{Message: "success",Data:    "",}, nil
}

核心代碼,就是將原來直接的rpc 調用,委托給 dtm 調用。

4. 修改服務端

  1. 修改 user-score/internal/logic/savescorelogic.go 文件
    引入 dtm
  2. 修改 user/internal/logic/userlogic.go 文件

5. 測試

在這里插入圖片描述

指定id,插入用于,測試成功。

6. 測試事務

現在模擬 user-score 服務的邏輯出現了問題。檢查事務是否生效。

在這里插入圖片描述
我們用 postman測試后,發現, user 表中插入了新的數據,但是積分表中是沒有新數據的。那是否事務沒有生效呢?
在這里插入圖片描述
當從后臺打印的日志可以看出,saveCallback 方法被調用。

這里需要明白一點。

userapi/internal/logic/userapilogic.go 代碼邏輯如下:

在這里插入圖片描述
代碼提交到了 dtm 分支。代碼

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/14623.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/14623.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/14623.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【代碼隨想錄 二叉樹】二叉樹前序、中序、后序遍歷的迭代遍歷

文章目錄 1. 二叉樹前序遍歷(迭代法)2. 二叉樹后序遍歷(迭代法)3. 二叉樹中序遍歷(迭代法) 1. 二叉樹前序遍歷(迭代法) 題目連接 🍎因為處理順序和訪問順序是一致的。所…

前端工程化-babel、corejs、postcss

出處:前端工程化-babel、corejs、postcss | 劉維_個人博客_編程秘籍_開發技巧_入門到精通_生活感悟 (ldlw.site) 一. babel和corejs的作用到底是什么 腦子里面的想法 es6 -> es5 es6里面其實有兩種東西 語法 新特性 轉的語法 const a 1 const b &#xf…

Shader GLSL 3D旋轉函數

mat4 rotationMatrix(vec3 axis, float angle) {axis = normalize(axis);float s = sin(angle);float c = cos(angle)

類和對象的基本概念

類和對象的基本概念 C和C中struct區別類的封裝封裝訪問權限總結struct和class的區別 將成員變量設置為private C和C中struct區別 C語言struct只有變量C語言struct 既有變量,也有函數 類的封裝 封裝 把變量(屬性)和函數(操作&a…

交換機部分綜合實驗

實驗要求 1.內網IP地址使用172.16.0.0/16 2.sw1和sW2之間互為備份; 3.VRRP/mstp/vlan/eth-trunk均使用; 4.所有pc均通過DHcP獲取Ip地址; 5.ISP只配置IP地址; 6.所有電腦可以正常訪問IsP路由器環回 實驗拓撲 實驗思路 1.給交換機創建vlan,并將接口劃入vlan 2.在SW1和…

Unity Render Streaming 云渲染 外網訪問

初版: 日期:2024.5.20 前言:臨時思路整理,后期會詳細補充 環境: 1. 阿里云服務器 需要安裝好nodejs 、npm 2. windows電腦,需安裝好 nodejs 、npm 3.Unity 2021.3.15f1 4.Unity Render Streaming …

31.GDB介紹及簡單使用

文章目錄 基本用法查看匯編代碼Text User Interface(TUI)refernece 歡迎訪問個人網絡日志🌹🌹知行空間🌹🌹 GDB 是 GNU Debugger的縮寫,是GNU軟件系統中的標準調試器, 很多類UNIX系統都可以使用GDB&#xf…

【論文解讀】Overview of the Scalable Video Coding Extension of the H.264/AVC Standard

介紹 該篇論文是一篇關于H.264/AVC標準可擴展視頻編碼(SVC)擴展的綜述論文,由Heiko Schwarz、Detlev Marpe和Thomas Wiegand撰寫,發表在《IEEE Transactions on Circuits and Systems for Video Technology》2007年9月第17卷第9期上。 論文解讀 摘要: H.264/AVC視頻編…

鄉村振興的農業供給側結構性改革:優化農業產業結構,提升農產品質量,滿足市場需求,實現美麗鄉村產業振興

一、引言 鄉村振興戰略是我國當前及未來一段時間內的重大戰略部署,旨在推動農業農村現代化,實現城鄉融合發展。在鄉村振興戰略中,農業供給側結構性改革是核心任務之一。通過優化農業產業結構、提升農產品質量、滿足市場需求,不僅…

韓國云主機遠程故障怎么排查?

韓國云主機遠程故障可能是由于多種原因引起的,包括網絡問題、服務器故障、安全設置、客戶端問題等。下面是針對韓國云主機遠程故障的排查步驟和解決方法: 檢查網絡連接 1.使用 ping 命令 在本地計算機上使用 ping 命令檢查與云主機之間的網絡連接。如果無…

AI巨頭爭相與Reddit合作:為何一個古老的論壇成為AI訓練的“寶藏”?

每周跟蹤AI熱點新聞動向和震撼發展 想要探索生成式人工智能的前沿進展嗎?訂閱我們的簡報,深入解析最新的技術突破、實際應用案例和未來的趨勢。與全球數同行一同,從行業內部的深度分析和實用指南中受益。不要錯過這個機會,成為AI領…

debian nginx upsync consul 實現動態負載

1. consul 安裝 wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg echo "deb [signed-by/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_r…

MariaDB 給指定列值自動加密(持久數據加觸發器)

文章目錄 代碼插入時,自動加密更新時,自動加密查看觸發器數據操作示例update數據取出解密取 注意一次嘗試,看加密后數據長度 參考鏈接: 一篇非常好的講解觸發器的文章:示例、原理MySQL/MariaDB觸發器。 用觸發器自動加…

前端工程化07-常見的包管理工具npm、yarn、cnpm、npx、pnpm

8、包管理工具 8.1、包管理工具概述 npm包管理工具、在安裝node的時候這個東西就已經安裝過了,通過npm去管理包的時候這個時候回有一個配置文件叫做package.json,他是以json的方式來書寫對應的一個配置文件,這個配置文件是可以添加特別多的一些字段的&…

input輸入多行文本,保存為.dot文件和對應的.txt文件

需求 不管是上面的dot還是這個dot 變成 input輸入文本按“# ? ?”結束保存在dot文本文件夾下,用txt保存每個文件文件名: 編號. 第二行有字文字 時間戳 代碼 首先,我會創建一個Python腳本,它將接受用戶的輸入,直到…

案例題(第二版)

案例題目 信息系統架構設計 基本概念 信息系統架構(ISA)是對某一特定內容里的信息進行統籌、規劃、設計、安排等一系列的有機處理的活動。特點如下 架構是對系統的抽象,它通過描述元素、元素的外部可見屬性及元素之間的關系來反映這種抽象…

css屬性之間總是有換行

問題 在create-next-app創建項目的時候,只要我沒有選擇eslint的時候,就不會在保存的時候每個屬性之間有換行,但是創建項目的時候選擇eslint,保存的時候就會在每條屬性間有換行 回答 當你使用 create-next-app 創建項目并選擇使用 ESLint 時…

k8s 1.28.10 瀏覽器訪問6443查看api,需要證書

添加證書 使用client-certificate-data和client-key-data生成一個p12文件 1.生成client-certificate-data grep client-certificate-data ~/.kube/config | head -n 1 | awk {print $2} | base64 -d >> kubecfg.crt2.生成client-key-data grep client-key-data ~/.kub…

萬象生圖,一個windows文生圖的軟件

網址 https://support.qq.com/products/637894/?id155553 支持文生圖,支持提示詞本地翻譯,支持提示詞權重語法,支持樣例和風格 支持圖處理,包括去除背景和圖像放大 支持各種快速生圖模型,如LCM、TCD、Lightning、…

為什么self-attention要除以一個根號dk

簡單說法是為了讓方差到1,推公式也好推。但是沒幾個人說為什么方差要到1. 如果不除以根號dk,顯然QK有可能很大,這就讓softmax更有能力得到接近one-hot的結果。這本應是好的,但是從實踐來看,我們并不要求一定要輸出one-…