基于go微服務(wù)效率工具goctl深度解析
前言
本文根據(jù)安前松的視頻分享整理而來,視頻回放地址如下:
一、goctl 的由來
1. goctl 的誕生
goctl 的最早功能是為了解決 GRPC 內(nèi)網(wǎng)調(diào)試問題,大約是在 2019 年,在我們的生產(chǎn)環(huán)境中,rpc 是內(nèi)網(wǎng)隔離的,不可通過外網(wǎng)訪問,為了快速去 mock 一些線上 RPC client 的請求,就簡單的實現(xiàn)了第一版本的代碼生成,主要目的是去訪問 RPC Server 做一些調(diào)試。
2. 為什么需要 goctl?
降低溝通成本
溝通,是團隊協(xié)作進行信息交換的一種形式,溝通的方式有很多種,會議溝通、文檔溝通、聊天交流,相信不管是哪種方式,溝通都是團隊中最難的一個環(huán)節(jié),會議溝通需要占用大量時間,動則半小時起步,文檔溝通同樣,也會占據(jù)大量時間去構(gòu)思和編寫大篇幅的文檔,最后可能還沒表達出預(yù)期目標,線上聊天,需要雙方都在線上才能進行信息交換,當然我們這里溝通交換的信息更多是指開發(fā)中的一些內(nèi)容,如接口信息、部署信息等。
降低團隊耦合
有了溝通,那么團隊之間的協(xié)作的耦合是避免不了的,例如:在前后端開發(fā)中,最大的耦合是接口的耦合,前端完成了規(guī)定 UI 繪制后,需要等待后端的接口部署到對應(yīng)環(huán)境才能實現(xiàn)功能的調(diào)試,在此期間,前端的團隊資源就會大大浪費,由此還會導(dǎo)致項目的延期等問題。
提高開發(fā)效率
除了溝通成本和團隊耦合以外,每個團隊在進行項目開發(fā)時也有很多時間是在做重復(fù)的工作,例如:我們在開發(fā)一個新的功能時,需要去定義接口,編寫接口文檔,編碼準備工作,業(yè)務(wù)開發(fā),model 文件,編寫 Dockerfile 文件,編寫 k8s yaml 文件,在這些上面我們可以在每個環(huán)節(jié)上都有提升的空間,讓用戶將真正的時間集中在業(yè)務(wù)開發(fā)上。
降低錯誤率
在之前的開發(fā)實踐中,經(jīng)常會出現(xiàn) grpc server 實現(xiàn)不完全的問題,grpc server 實現(xiàn)類經(jīng)常會出現(xiàn)編譯不過的情況;除此之外,數(shù)據(jù)庫查詢層代碼開發(fā),sql 語句的編寫多參,少參,參數(shù)錯位,在編譯過程中很難發(fā)現(xiàn),一般可能到 QA 環(huán)節(jié)才能發(fā)現(xiàn),更甚者會導(dǎo)致線上問題。
3. 怎么理解開發(fā)規(guī)范?
開發(fā)規(guī)范,包括編碼規(guī)范,工程規(guī)范,提交規(guī)范,代碼審核規(guī)范,部署規(guī)范等等,團隊內(nèi)如果將開發(fā)規(guī)范統(tǒng)一起來,其收益可想而知,舉個例子:假如你所在的公司沒有統(tǒng)一開發(fā)規(guī)范,這時需要你去做一些跨部門協(xié)作或者支持,煥然一新的開發(fā)環(huán)境讓你望而卻步,還沒開始就有了抵觸的念頭,這豈不是違背了支持的初衷。
4. 怎么理解工程效率?
工程效率,要理解工程效率,可以先看看『效率』的定義:
效率是指單位時間內(nèi)完成的工作量
效率的目標是快,但快并不是效率,換句話說就是在單位時間內(nèi)完成的高質(zhì)量工作,這才是我們要追求的目標,那么工程效率就是為了『縮短從開發(fā)到線上的距離』
二 、goctl 的安裝及功能介紹
1. 介紹
goctl 定義
goctl 定義,準確說是定位吧,可以理解為一個代碼生成腳手架,其核心思想是通過對 DSL 進行語法解析、語義分析到數(shù)據(jù)驅(qū)動實現(xiàn)完成代碼生成功能,旨在幫助開發(fā)者從工程效率角度提高開發(fā)者的開發(fā)效率。
解決的問題
- 提高開發(fā)效率:goctl 的代碼生成覆蓋了Go、Java、Android、iOS、TS 等多門語言,通過 goctl 可以一鍵生成各端代碼,讓開發(fā)者將精力集中在業(yè)務(wù)開發(fā)上。
- 降低溝通成本:使用 zero-api 替代 API 文檔,各端以 zero-api 為中心生成各端代碼,無需再通過會議、API 文檔來進行接口信息傳遞。
- 降低耦合度: 在之前的開發(fā)實踐中,沒有 goctl 之前,我們采用的是傳統(tǒng)的 API 文檔來作為接口信息傳遞的載體,然后通過會議來進行二次 review,我們都知道,前端開發(fā)工作中,除了 UI 的繪制外就是 UI 聯(lián)調(diào),如果比較積極的前端開發(fā)者,可能會自己利用一些腳手架或者自己 mock 一些數(shù)據(jù)去進行 UI 聯(lián)調(diào),反之,也有原地等待后端部署后再聯(lián)調(diào)的 case,原因是自己寫 mock 數(shù)據(jù)太耗時,也不想去動,如果前端的開發(fā)進度在后端之前,那么在后端部署到環(huán)境中這期間,前端只能安靜的原地等待,這不僅是一種資源的浪費,也會造成項目進度的延期,有了 zero-api ,前端可以利用 goctl 去生成適量的 mock 數(shù)據(jù)來進行 UI聯(lián)調(diào)。
發(fā)展歷史
goctl 發(fā)展歷史可以大概的過一下,挑幾個標志性的功能講講吧!
首先是 goctl rpc,goctl rpc 的第一版本就是 goctl 的雛形,主要是為了生成 client 代碼對 rpc 做調(diào)試使用,具體就不展開了。goctl rpc 的發(fā)展經(jīng)過了很多曲折,印象比較深刻的應(yīng)該算 goctl rpc proto 向 goctl rpc protoc 的轉(zhuǎn)變,這期間為了解決很多問題,才做了相應(yīng)的變更,具體細節(jié)在分享 rpc 代碼生成使用那塊再詳細分享,在這里面其實對我來說印象最深刻的一個功能算是 goctl model 了,其算是我開始維護 goctl 的一個入手點吧,也是我從業(yè)務(wù)開發(fā)實踐中挖掘的解決方案吧,終究我還是比較 "懶",記得在當時開發(fā)一個業(yè)務(wù)模塊,由于業(yè)務(wù)比較大,需要創(chuàng)建的數(shù)據(jù)表也很多,在沒有 goctl 前都是自己去手動編碼完成,這一塊我記憶猶新,花了僅一天的時間來寫 model 文件,因為我沒有用 orm 的習(xí)慣,所以這塊 sql 完全是裸 sql 語句,服務(wù)跑起來后才發(fā)現(xiàn)有很多 sql 傳參上的錯誤,基本都是多參少參問題,除此之外,每次新增索引,或者字段變更,緩存的相關(guān)邏輯維護也讓我十分頭疼,于是結(jié)合當時的開發(fā)最佳實踐,將其按照緩存與否把這塊的工作交給了 goctl,第一版本 goctl model 生成主要是網(wǎng)頁版本,后面陸續(xù)集成到 goctl 里了,這給我后續(xù)開發(fā)帶來了很大的開發(fā)效率收益。
展望未來
goctl 集成了比較多的功能,其基本是以代碼生成為主,開發(fā)規(guī)范為輔,goctl 是圍繞 zero-api 為中心做代碼生成的,因此在將來,zero-api 的建設(shè)會成為我們的重心:
- ast 的改造:替換原有比較重的 antlr4,可以解決很多人安裝 goctl 時 內(nèi)存不夠,系統(tǒng)架構(gòu)不支持的各種問題,這
- goctl mock 的支持,最大限度解耦各端依賴耦合
2. 安裝
Goctl 安裝有兩種方式,分別是 go get 或者 go install,其次是 docker。
go get/install
# Go 1.16 之前版本 $ GO111MODULE=on GOPROXY=https://goproxy.cn/,direct go get -u github.com/zeromicro/go-zero/tools/goctl@latest # Go 1.16 及以后版本 $ GOPROXY=https://goproxy.cn/,direct go install github.com/zeromicro/go-zero/tools/goctl@latest # macOS $ brew install goctl # 驗證 $ goctl --version goctl version 1.3.5 darwin/amd64 # 查看 goctl $ cd $GOPATH/bin && ls | grep "goctl"
如果執(zhí)行 goctl --version 提示 command not found: goctl 的錯誤,請先排查 $GOBIN 是否在環(huán)境變量下。
docker
# 1. pull $ docker pull kevinwan/goctl .... # 2. ls $ docker image ls | grep "goctl" kevinwan/goctl latest 7fd46843de3d 5 weeks ago 383MB # 3. run $ docker run -it kevinwan/goctl /bin/sh
3. 功能介紹
我們接下來看看功能介紹,通過指令 goctl --help 可以列出我們當前已經(jīng)支持的功能,可能大家在看文檔時也沒有專心下來對這塊指令做研究,只是用到一些高頻指令,今天既然是 goctl 的專題分享,我們就花點時間來一起過過,帶著大家從 0 到 1 熟悉 goctl。
$ goctl --help A cli tool to generate api, zrpc, model code Usage: goctl [command] Available Commands: api Generate api related files bug Report a bug completion Generate the autocompletion script for the specified shell docker Generate Dockerfile env Check or edit goctl environment help Help about any command kube Generate kubernetes files migrate Migrate from tal-tech to zeromicro model Generate model code quickstart quickly start a project rpc Generate rpc code template Template operation upgrade Upgrade goctl to latest version Flags: -h, --help help for goctl -v, --version version for goctl Use "goctl [command] --help" for more information about a command.
goctl 的功能比較豐富,所以難免指令參數(shù)比較多,大家在使用時除了看文檔外,也善用 --help 這個flag,因為他會告訴你每個指令或者子指令的用法,需要什么參數(shù),參數(shù)類型是字符串還是布爾,是必填還是可選,切不可自己猜測他應(yīng)該用什么 flag,雖然 goctl 是我自己主要維護,其實很多時候,有些指令比較文檔,沒有太多 feature 去更新,我也記不住,我也是通過 --help 去查看功能介紹的
goctl completion
查看 goctl 版本
$ goctl --version goctl version 1.3.5 darwin/amd64
1.3.5
本節(jié)內(nèi)容僅適合 goctl 版本在 1.3.5及之前的的自動補全設(shè)置參考,1.3.5版本及之前僅支持類 Unix 操作系統(tǒng),不支持 Windows 的自動補全,1.3.5 之后的請?zhí)^此節(jié)內(nèi)容
- 執(zhí)行 goctl completion -h 查看使用說明
$ goctl completion --help NAME: goctl completion - generation completion script, it only works for unix-like OS USAGE: goctl completion [command options] [arguments...] OPTIONS: --name value, -n value the filename of auto complete script, default is [goctl_autocomplete]
根據(jù)幫助說明得知,goctl completion 支持通過 --name 傳遞一個參數(shù)生成自動補全腳本文件名,但該參數(shù)為非必填,默認不填時為goctl_autocomplete 文件,其位于 $GOCTLHOME 目錄下。
- 執(zhí)行 goctl completion 來生成自動補全腳本
$ goctl completion generation auto completion success! executes the following script to setting shell: echo PROG=goctl source /Users/keson/.goctl/.auto_complete/zsh/goctl_autocomplete >> ~/.zshrc && source ~/.zshrc # 或者 echo PROG=goctl source /Users/keson/.goctl/.auto_complete/bash/goctl_autocomplete >> ~/.bashrc && source ~/.bashrc
- 查看當前 shell
$ echo $SHELL /bin/zsh
- 選擇對應(yīng) shell 的腳本執(zhí)行,我這里為 zsh,所以執(zhí)行指令如下
$ echo PROG=goctl source /Users/keson/.goctl/.auto_complete/zsh/goctl_autocomplete >> ~/.zshrc && source ~/.zshrc
- 重啟終端驗證結(jié)果
# 鍵入 goctl 后按下 tab 鍵查看自動補全提示 $ goctl # tab api -- generate api related files bug -- report a bug completion -- generation completion script, it only works for unix-like OS docker -- generate Dockerfile env -- check or edit goctl environment help h -- Shows a list of commands or help for one command kube -- generate kubernetes files migrate -- migrate from tal-tech to zeromicro model -- generate model code rpc -- generate rpc code template -- template operation upgrade -- upgrade goctl to latest version
1.3.6
本節(jié)內(nèi)容僅適合 goctl 版本在 1.3.6 及之后的的自動補全設(shè)置參考,1.3.6 之前的請?zhí)^此節(jié)內(nèi)容
- 如果你是從 1.3.5 升級到 1.3.6 及以后,則需要執(zhí)行如下指令來清除舊版本自動補全配置,這里以 zsh 為例子,否則請?zhí)^這一步
# 編輯 ~/.zshrc $ vim ~/.zshrc # 找到 PROG=goctl 所在行并刪除 # source $ source ~/.zshrc && rm .zcompdump* # 重啟終端
- 執(zhí)行 goctl completion -h 查看使用說明,從使用幫助中可以查看到目前支持 bash、fish 、powershell、zsh 4 種 shell 的自動補全。
$ goctl completion --help Generate the autocompletion script for goctl for the specified shell. See each sub-command's help for details on how to use the generated script. Usage: goctl completion [command] Available Commands: bash Generate the autocompletion script for bash fish Generate the autocompletion script for fish powershell Generate the autocompletion script for powershell zsh Generate the autocompletion script for zsh Flags: -h, --help help for completion Use "goctl completion [command] --help" for more information about a command.
- 查看當前使用的 shell
$ echo $SHELL /bin/zsh
- 由于當前使用的 zsh,所以我們來看一下 zsh 的自動補全設(shè)置幫助
$ goctl completion zsh --help Generate the autocompletion script for the zsh shell. If shell completion is not already enabled in your environment you will need to enable it. You can execute the following once: echo "autoload -U compinit; compinit" >> ~/.zshrc To load completions for every new session, execute once: #### Linux: goctl completion zsh > "${fpath[1]}/_goctl" #### macOS: goctl completion zsh > /usr/local/share/zsh/site-functions/_goctl You will need to start a new shell for this setup to take effect. Usage: goctl completion zsh [flags] Flags: -h, --help help for zsh --no-descriptions disable completion descriptions
從上文可以看出,根據(jù)操作系統(tǒng)的不同,自動補全的設(shè)置方式也不一樣,我這里是 macOS,我們執(zhí)行一下對應(yīng)的指令:
$ goctl completion zsh > /usr/local/share/zsh/site-functions/_goctl
我們先重開一個終端來試一下:
# 鍵入 goctl 后按下 tab 鍵查看自動補全提示 $ goctl # tab api -- Generate api related files bug -- Report a bug completion -- Generate the autocompletion script for the specified shell docker -- Generate Dockerfile env -- Check or edit goctl environment help -- Help about any command kube -- Generate kubernetes files migrate -- Migrate from tal-tech to zeromicro model -- Generate model code quickstart -- quickly start a project rpc -- Generate rpc code template -- Template operation upgrade -- Upgrade goctl to latest version
常見錯誤
- goctl Error: unknown flag: --generate-goctl-completion
- (eval):1: command not found: _goctl 按照 1.3.6 自動補全配置重新進行配置
goctl migrate
幫助開發(fā)者從1.3.0 之前版本無縫遷移到 1.3.0及后的任意版本,如果使用的 go-zero 版本本身就是 1.3.0 及之后的,則無需做此操作。
為什么需要遷移?
go-zero 在 1.3.0 版本做了組織變更,即用 zeromicro 替換原來的 tal-tech 組織名稱。
我現(xiàn)在有一個演示項目 awesomemigrate 是用舊版本 goctl 生成的,該項目的 go-zero 的 module 為
module awesomemigrate go 1.18 require github.com/tal-tech/go-zero v1.2.5 ...
假設(shè)我們需要將該項目的 go-zero 升級至截止目前最新版本 1.3.3 ,要完成項目從 tal-tech 到 zeromicro 的升級 前需要確保 goctl 版本大于 v1.3.2,然后在執(zhí)行 goctl 遷移指令執(zhí)行,如果 goctl 版本小于 v1.3.2,則需要升級。
# 1. 查看當前 goctl 版本 $ goctl --version goctl version 1.2.5 darwin/amd64 # 2. 由于 goctl 版本小于 v1.3.2,則需要升級至最新,如果 goctl 版本已經(jīng)是1.3.2及之后了,則可以不用升級 $ go install github.com/zeromicro/go-zero/tools/goctl@latest # 3. 查看一下遷移指令使用幫助 $ goctl migrate --help NAME: goctl migrate - migrate from tal-tech to zeromicro USAGE: goctl migrate [command options] [arguments...] DESCRIPTION: migrate is a transition command to help users migrate their projects from tal-tech to zeromicro version OPTIONS: --verbose, -v verbose enables extra logging --version value the target release version of github.com/zeromicro/go-zero to migrate # 4. 進入待遷移的項目下,執(zhí)行遷移指令 $ goctl migrate --version 1.3.3 # 5. 驗證依賴是否存在問題 $ go test . ? awesomemigrate [no test files]
遷移完成后,我們再來看看 module 文件
module awesomemigrate go 1.18 require github.com/zeromicro/go-zero v1.3.3 ...
在 project 搜索一下 tal-tech的匹配結(jié)果會發(fā)現(xiàn)為0:
goctl env
goctl env 主要是用于環(huán)境檢測、安裝、環(huán)境參數(shù)控制等功能,除此之外還可以查看當前 goctl 的一些環(huán)境信息,以至于用戶在遇到 bug 時可以根據(jù)此環(huán)境上報當前 goctl 處于的環(huán)境。
首先我們看看其使用說明
$ goctl env --help NAME: goctl env - check or edit goctl environment USAGE: goctl env command [command options] [arguments...] COMMANDS: install goctl env installation check detect goctl env and dependency tools OPTIONS: --write value, -w value edit goctl environment --help, -h show help
goctl env 支持環(huán)境查看、參數(shù)修改、依賴檢測安裝幾個功能,我們依次來看一下
環(huán)境查看
在不輸入任何 flag 的情況下,則是查看當前 goctl 環(huán)境。
$ goctl env GOCTL_OS=darwin GOCTL_ARCH=amd64 GOCTL_HOME=/Users/keson/.goctl GOCTL_DEBUG=false GOCTL_CACHE=/Users/keson/.goctl/cache GOCTL_VERSION=1.3.5 PROTOC_VERSION=3.19.4 PROTOC_GEN_GO_VERSION=v1.27.1 PROTO_GEN_GO_GRPC_VERSION=1.2.0
以上參數(shù)的大概說明為
參數(shù)名稱 | 參數(shù)類型 | 參數(shù)說明 |
---|---|---|
GOCTL_OS | STRING | 當前操作系統(tǒng),常見值有 darwin、windows、linux 等 |
GOCTL_ARCH | STRING | 當前系統(tǒng)架構(gòu),常見值有 amd64, 386 等 |
GOCTL_HOME | STRING | 默認為 ~/.goctl |
GOCTL_DEBUG | BOOLEAN | 是否開啟 debug 模式,默認為 false,目前暫未使用,主要是 goctl 開發(fā)中可能用于控制調(diào)試模式 |
GOCTL_CACHE | STRING | goctl 緩存目錄,主要緩存下載的依賴 protoc、protoc-gen-go、protoc-gen-go-grpc等 |
GOCTL_VERSION | STRING | 當前 goctl 版本 |
PROTOC_VERSION | STRING | 當前 protoc 版本,如未安裝則為空字符串 |
PROTOC_GEN_GO_VERSION | STRING | 當前 protoc-gen-go 版本,如未安裝或者從github.com/golang/protobuf 安裝版本為 v1.3.2 之前的則為空字符串 |
PROTO_GEN_GO_GRPC_VERSION | STRING | 當前 protoc-gen-go-grpc版本,如未安裝則為空字符串 |
修改參數(shù)
比如我們將 GOCTL_DEBUG 修改為 true
# 修改前 $ goctl env | grep 'GOCTL_DEBUG' GOCTL_DEBUG=false # 修改 GOCTL_DEBUG 為 true $ goctl env -w GOCTL_DEBUG=true # 修改后 goctl env | grep 'GOCTL_DEBUG' GOCTL_DEBUG=true
依賴檢測/安裝
我們來檢測一下我當前的依賴都是否安裝好,目前依賴檢測內(nèi)容為protoc、protoc-gen-go、protoc-gen-go-grpc
# 我們來檢查一下依賴安裝 $ goctl env check --verbose [goctl-env]: preparing to check env [goctl-env]: looking up "protoc" [goctl-env]: "protoc" is not found in PATH [goctl-env]: looking up "protoc-gen-go" [goctl-env]: "protoc-gen-go" is not found in PATH [goctl-env]: looking up "protoc-gen-go-grpc" [goctl-env]: "protoc-gen-go-grpc" is not found in PATH [goctl-env]: check env finish, some dependencies is not found in PATH, you can execute command 'goctl env check --install' to install it, for details, please execute command 'goctl env check --help' # 安裝依賴,安裝依賴有2中方式 # 方式一 # $ goctl env check --install --force --verbose # 方式二 $ goctl env install --verbose -f [goctl-env]: preparing to check env [goctl-env]: looking up "protoc" [goctl-env]: "protoc" is not found in PATH [goctl-env]: preparing to install "protoc" [goctl-env]: "protoc" is already installed in "/Users/keson/go/bin/protoc" [goctl-env]: looking up "protoc-gen-go" [goctl-env]: "protoc-gen-go" is not found in PATH [goctl-env]: preparing to install "protoc-gen-go" [goctl-env]: "protoc-gen-go" is already installed in "/Users/keson/go/bin/protoc-gen-go" [goctl-env]: looking up "protoc-gen-go-grpc" [goctl-env]: "protoc-gen-go-grpc" is not found in PATH [goctl-env]: preparing to install "protoc-gen-go-grpc" [goctl-env]: "protoc-gen-go-grpc" is already installed in "/Users/keson/go/bin/protoc-gen-go-grpc" [goctl-env]: congratulations! your goctl environment is ready!
goctl rpc
首先我們來看一下該指令的使用幫助
goctl rpc -h Generate rpc code Usage: goctl rpc [flags] goctl rpc [command] Available Commands: new Generate rpc demo service protoc Generate grpc code template Generate proto template Flags: --branch string The branch of the remote repo, it does work with --remote -h, --help help for rpc --home string The goctl home path of the template, --home and --remote cannot be set at the same time, if they are, --remote has higher priority --o string Output a sample proto file --remote string The remote git repo of the template, --home and --remote cannot be set at the same time, if they are, --remote has higher priority The git repo directory must be consistent with the https://github.com/zeromicro/go-zero-template directory structure Use "goctl rpc [command] --help" for more information about a command.
該指令提供了三個子指令,new 是快速創(chuàng)建一個 zrpc 服務(wù),protoc 是根據(jù) proto 描述文件生成 zrpc 代碼,而 template 則是快速生成一個 proto 模板,我們將重點圍繞 goctl rpc protoc 指令來展開,看看 goctl rpc protoc 的使用說明:
goctl rpc protoc -h Generate grpc code Usage: goctl rpc protoc [flags] Examples: goctl rpc protoc xx.proto --go_out=./pb --go-grpc_out=./pb --zrpc_out=. Flags: --branch string The branch of the remote repo, it does work with --remote -h, --help help for protoc --home string The goctl home path of the template, --home and --remote cannot be set at the same time, if they are, --remote has higher priority --remote string The remote git repo of the template, --home and --remote cannot be set at the same time, if they are, --remote has higher priority The git repo directory must be consistent with the https://github.com/zeromicro/go-zero-template directory structure --style string The file naming format, see [https://github.com/zeromicro/go-zero/tree/master/tools/goctl/config/readme.md] (default "gozero") -v, --verbose Enable log output --zrpc_out string The zrpc output directory
goctl rpc protoc 到底怎么使用,為什么示例里面有 --go_out、--go-grpc_out 參數(shù),而查看 help 的時候卻沒有看到介紹?目前我們先這樣理解,我們先拋開 goctl,根據(jù)官方 protoc 生成 grpc 代碼時的指令是什么?會用到哪些 flag,對于 zrpc 的代碼生成,你可以理解為 goctl 生成 zrpc 只是在生成 grpc 代碼指令的基礎(chǔ)上加了 goctl rpc 前綴和一些 goctl 生成 zrpc 需要的 flag,而對于 protoc 及 插件 protoc-gen-go 、 protoc-gen-grpc-go 的相關(guān)參數(shù) goctl 只是做繼承,沒有必要顯示的在 help 里面再描述一遍,后面在分析源碼時可以給大家詳細講解一些這塊的設(shè)計和考慮,接下來我們用一個例子來演示一下,假設(shè)我們有一個 greet.proto 文件,拋開 goctl ,我們生成 grpc 代碼需要執(zhí)行的指令如下:
如果不知道 grpc 代碼是怎么生成的,這塊建議參考官方文檔 grpc.io/
# 進入 greet.proto 所在目錄 $ protoc greet.proto --go_out . --go-grpc_out . $ tree . ├── greet.proto └── pb ├── greet.pb.go └── greet_grpc.pb.go
那么按照上文對 goctl rpc protoc 的介紹,我們生成 zrpc 代碼的指令則應(yīng)該為
# 這里多了一個 --zrpc_out 用于指定 zrpc 代碼的輸出目錄 $ goctl rpc protoc greet.proto --go_out=. --go-grpc_out=. --zrpc_out=. --verbose [goctl-env]: preparing to check env [goctl-env]: looking up "protoc" [goctl-env]: "protoc" is installed [goctl-env]: looking up "protoc-gen-go" [goctl-env]: "protoc-gen-go" is installed [goctl-env]: looking up "protoc-gen-go-grpc" [goctl-env]: "protoc-gen-go-grpc" is installed [goctl-env]: congratulations! your goctl environment is ready! [command]: protoc greet.proto --go_out . --go-grpc_out . Done. $ tree . ├── etc │ └── greet.yaml ├── go.mod ├── greet │ └── greet.go ├── greet.go ├── greet.proto ├── internal │ ├── config │ │ └── config.go │ ├── logic │ │ └── pinglogic.go │ ├── server │ │ └── greetserver.go │ └── svc │ └── servicecontext.go └── pb ├── greet.pb.go └── greet_grpc.pb.go 8 directories, 11 files
如果在生成代碼時需要輸出日志,可以加 --verbose 來顯示日志。
goctl rpc protoc 在生成 zrpc 代碼時會先對你的環(huán)境依賴進行檢測,如果沒有安裝則會自動安裝依賴再生成代碼。
編輯器插件
為了提升大家對 zero-api 文件的編寫效率,我們分別對 intellij 和 vscode 提供了相應(yīng)的編輯器插件, vscode 插件介紹及使用請參考 github.com/zeromicro/g…
三、goctl 使用中遇到的問題
goctl 從最初的一個功能 rpc proxy 到當前版本(v1.3.5) 已經(jīng)擁有13個一級指令和近30個二級指令, 期間 goctl 做了一些調(diào)整,而且,gcotl 本身的前進步伐也非常快,他更像是在摸索中前進,朝著更快,更好用的方向發(fā)展,因此在迭代的路上,goctl 會顯得有些不穩(wěn)定,大家興許也遇到很多問題,這里大概總結(jié)一下大家在社區(qū)中反饋比較多的一些問題來分享一下。
1. 386 架構(gòu)上安裝 goctl 失敗!
描述:antlr 生成的源碼中,沒有對 386 架構(gòu)的 uint 的邊界值進行很好的處理,導(dǎo)致邊界溢出
修復(fù)版本:v1.3.3
2. grpc 到底安裝什么版本插件?
描述:熟悉 grpc 的人應(yīng)該都知道,生成 grpc 代碼的插件 protoc-gen-go 有兩個倉庫在維護,有3 個安裝來源,2個維護倉庫分別是:
# 1. golang # github.com/golang/protobuf/protoc-gen-go # 2. protocolbuffers # github.com/protocolbuffers/protobuf-go/cmd/protoc-gen-go
三個安裝來源是
# 1. golang 維護的倉庫,目前已不推薦使用 # github.com/golang/protobuf/protoc-gen-go # 2. protocolbuffers 維護的,目前推薦使用的 # github.com/protocolbuffers/protobuf-go/cmd/protoc-gen-go # 3. goolge 安裝,這其實和第二種安裝的是一個二進制,他的源碼就是protocolbuffers 維護的相同倉庫 # google.golang.org/protobuf/cmd/protoc-gen-go
在 v.1.3.4前,如果使用 goctl rpc proto 生成 zrpc 代碼則建議安裝舊版本的插件,即 golang 維護的,因此該指令生成 zrpc 代碼是 goctl 為了用戶生成指令的簡單,做了很厚的封裝,但隨之帶來的問題就是難兼容,因此該指令已不推薦使用。
在v.1.3.4及以后,沒有對 protoc-gen-go 做限制,用戶可以自由選擇不同的來源進行安裝,但建議還是安裝 protocolbuffer 維護的版本(官方文檔已經(jīng)替換為這個),而且必須要安裝protoc-gen-grpc-go 插件,這樣做的目的是跟著 grpc 官方走,不過用戶不用有太大的心理負擔(dān),一下安裝這么多依賴,很麻煩,goctl 都已經(jīng)幫你實現(xiàn)了,你只要使用 goctl rpc protoc 生成代碼時會自動檢測依賴并安裝。
綜上所述,建議大家還在使用該指令的用戶盡早用 goctl rpc protoc 替代。
3. 錯誤提升
為什么 Windows 上生成 api/zrpc 代碼時,總是提示 The system cannot find the path specified
類似錯誤?
goctl.exe api go -api test.api -dir . Stat : The system cannot find the path specified.
描述:產(chǎn)生該原因是因為 go list -json -m
獲取 go module 時拿到的是一個固定值command-line-arguments,該問題已經(jīng)在 github.com/zeromicro/g… 進行修復(fù),版本將在 v1.3.6
生效。
4. No help topic 'proto'
描述:該指令在 v1.3.4
已經(jīng)移除,用 goctl rpc protoc
替代
5. zrpc 生成代碼時報 go_package 錯誤
protoc-gen-go: unable to determine Go import path for "greet.proto"
Please specify either:
• a "go_package" option in the .proto source file, or
• a "M" argument on the command line.
See https://developers.google.com/protocol-buffers/docs/reference/go-generated#package for more information.
--go_out: protoc-gen-go: Plugin failed with status code 1.
6. zrpc 生成代碼時指定了 pb 的輸出目錄為當前服務(wù) main 目錄
the output of pb.go and _grpc.pb.go must not be the same with --zrpc_out: pb output: /Users/keson/workspace/awesome-goctl/zwesome-zrpc/pb_in_main zrpc out: /Users/keson/workspace/awesome-goctl/zwesome-zrpc/pb_in_main
7. 為什么我的代碼生成的 pb client(不)帶 client 標志?
這是舊版本 goctl rpc proto
生成 zrpc 代碼時才有這個問題,目前已經(jīng)移除了該指令。
8. 為什么我生成的目錄結(jié)構(gòu)和文檔演示不一樣?
對于 goctl rpc protoc
生成 zrpc 代碼的目錄結(jié)構(gòu),總的結(jié)構(gòu)上是不會存在差異的,唯一存在差異的是 pb 的輸出目錄,這個取決于你指定的參數(shù)來控制,控制 pb 輸出目錄的因素有 go_opt
、go-grpc_opt
、go_package
9. 為什么我安裝了 goctl 編輯器插件還是不能高亮
打開 Goland 的設(shè)置,搜索 FileTypes 設(shè)置 api 文件后綴即可。
以上就是微服務(wù)效率工具 goctl 深度解析的詳細內(nèi)容,更多關(guān)于微服務(wù)效率工具 goctl 深度解析的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Golang使用gin框架實現(xiàn)一個完整的聊天室功能
由于我們項目的需要,我就研究了一下關(guān)于websocket的相關(guān)內(nèi)容,去實現(xiàn)一個聊天室的功能,經(jīng)過幾天的探索,現(xiàn)在使用Gin框架實現(xiàn)了一個完整的聊天室+消息實時通知系統(tǒng),感興趣的小伙伴歡迎閱讀本文2023-08-08使用go實現(xiàn)常見的數(shù)據(jù)結(jié)構(gòu)
這篇文章主要介紹了使用go實現(xiàn)常見的數(shù)據(jù)結(jié)構(gòu),本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-03-03golang 64位linux環(huán)境下編譯出32位程序操作
這篇文章主要介紹了golang 64位linux環(huán)境下編譯出32位程序操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-12-12Go語言動態(tài)并發(fā)控制sync.WaitGroup的靈活運用示例詳解
本文將講解 sync.WaitGroup 的使用方法、原理以及在實際項目中的應(yīng)用場景,用清晰的代碼示例和詳細的注釋,助力讀者掌握并發(fā)編程中等待組的使用技巧2023-11-11golang如何設(shè)置Header Content-type
這篇文章主要介紹了golang如何設(shè)置Header Content-type問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-01-01Go?channel實現(xiàn)批量讀取數(shù)據(jù)
Go中的?channel?其實并沒有提供批量讀取數(shù)據(jù)的方法,需要我們自己實現(xiàn)一個,使用本文就來為大家大家介紹一下如何通過Go?channel實現(xiàn)批量讀取數(shù)據(jù)吧2023-12-12