微服務效率工具 goctl 深度解析(上)

kevwan發表於2022-06-01

前言

本文根據 安前鬆 的視訊分享整理而來,視訊回放地址如下:

https://www.bilibili.com/video/BV1Hr4y1x7Ne

goctl 的由來

1. goctl 的誕生

goctl 的最早功能是為了解決 GRPC 內網除錯問題,大約是在 2019 年,在我們的生產環境中,rpc 是內網隔離的,不可通過外網訪問,為了快速去 mock 一些線上 RPC client 的請求,就簡單的實現了第一版本的程式碼生成,主要目的是去訪問 RPC Server 做一些除錯。

2. 為什麼需要 goctl?

  • 降低溝通成本

    溝通,是團隊協作進行資訊交換的一種形式,溝通的方式有很多種,會議溝通、文件溝通、聊天交流,相信不管是哪種方式,溝通都是團隊中最難的一個環節,會議溝通需要佔用大量時間,動則半小時起步,文件溝通同樣,也會佔據大量時間去構思和編寫大篇幅的文件,最後可能還沒表達出預期目標,線上聊天,需要雙方都線上上才能進行資訊交換,當然我們這裡溝通交換的資訊更多是指開發中的一些內容,如介面資訊、部署資訊等。

  • 降低團隊耦合

    有了溝通,那麼團隊之間的協作的耦合是避免不了的,例如:在前後端開發中,最大的耦合是介面的耦合,前端完成了規定 UI 繪製後,需要等待後端的介面部署到對應環境才能實現功能的除錯,在此期間,前端的團隊資源就會大大浪費,由此還會導致專案的延期等問題。

  • 提高開發效率

    除了溝通成本和團隊耦合以外,每個團隊在進行專案開發時也有很多時間是在做重複的工作,例如:我們在開發一個新的功能時,需要去定義介面,編寫介面文件,編碼準備工作,業務開發,model 檔案,編寫 Dockerfile 檔案,編寫 k8s yaml 檔案,在這些上面我們可以在每個環節上都有提升的空間,讓使用者將真正的時間集中在業務開發上。

  • 降低錯誤率

    在之前的開發實踐中,經常會出現 grpc server 實現不完全的問題,grpc server 實現類經常會出現編譯不過的情況;除此之外,資料庫查詢層程式碼開發,sql 語句的編寫多參,少參,引數錯位,在編譯過程中很難發現,一般可能到 QA 環節才能發現,更甚者會導致線上問題。

3. 怎麼理解開發規範?

開發規範,包括編碼規範,工程規範,提交規範,程式碼稽核規範,部署規範等等,團隊內如果將開發規範統一起來,其收益可想而知,舉個例子:假如你所在的公司沒有統一開發規範,這時需要你去做一些跨部門協作或者支援,煥然一新的開發環境讓你望而卻步,還沒開始就有了牴觸的念頭,這豈不是違背了支援的初衷。

4. 怎麼理解工程效率?

工程效率,要理解工程效率,可以先看看『效率』的定義:

效率是指單位時間內完成的工作量

效率的目標是快,但快並不是效率,換句話說就是在單位時間內完成的高質量工作,這才是我們要追求的目標,那麼工程效率就是為了『縮短從開發到線上的距離』

二 、goctl 的安裝及功能介紹

1. 介紹

  • goctl 定義

    goctl 定義,準確說是定位吧,可以理解為一個程式碼生成腳手架,其核心思想是通過對 DSL 進行語法解析、語義分析到資料驅動實現完成程式碼生成功能,旨在幫助開發者從工程效率角度提高開發者的開發效率。

  • 解決的問題

    • 提高開發效率:goctl 的程式碼生成覆蓋了Go、Java、Android、iOS、TS 等多門語言,通過 goctl 可以一鍵生成各端程式碼,讓開發者將精力集中在業務開發上。
    • 降低溝通成本:使用 zero-api 替代 API 文件,各端以 zero-api 為中心生成各端程式碼,無需再通過會議、API 文件來進行介面資訊傳遞。
    • 降低耦合度: 在之前的開發實踐中,沒有 goctl 之前,我們採用的是傳統的 API 文件來作為介面資訊傳遞的載體,然後通過會議來進行二次 review,我們都知道,前端開發工作中,除了 UI 的繪製外就是 UI 聯調,如果比較積極的前端開發者,可能會自己利用一些腳手架或者自己 mock 一些資料去進行 UI 聯調,反之,也有原地等待後端部署後再聯調的 case,原因是自己寫 mock 資料太耗時,也不想去動,如果前端的開發進度在後端之前,那麼在後端部署到環境中這期間,前端只能安靜的原地等待,這不僅是一種資源的浪費,也會造成專案進度的延期,有了 zero-api ,前端可以利用 goctl 去生成適量的 mock 資料來進行 UI聯調。
  • 發展歷史

goctl 發展歷史可以大概的過一下,挑幾個標誌性的功能講講吧!

首先是 goctl rpc,goctl rpc 的第一版本就是 goctl 的雛形,主要是為了生成 client 程式碼對 rpc 做除錯使用,具體就不展開了。goctl rpc 的發展經過了很多曲折,印象比較深刻的應該算 goctl rpc proto 向 goctl rpc protoc 的轉變,這期間為了解決很多問題,才做了相應的變更,具體細節在分享 rpc 程式碼生成使用那塊再詳細分享,在這裡面其實對我來說印象最深刻的一個功能算是 goctl model 了,其算是我開始維護 goctl 的一個入手點吧,也是我從業務開發實踐中挖掘的解決方案吧,終究我還是比較 "懶",記得在當時開發一個業務模組,由於業務比較大,需要建立的資料表也很多,在沒有 goctl 前都是自己去手動編碼完成,這一塊我記憶猶新,花了僅一天的時間來寫 model 檔案,因為我沒有用 orm 的習慣,所以這塊 sql 完全是裸 sql 語句,服務跑起來後才發現有很多 sql 傳參上的錯誤,基本都是多參少參問題,除此之外,每次新增索引,或者欄位變更,快取的相關邏輯維護也讓我十分頭疼,於是結合當時的開發最佳實踐,將其按照快取與否把這塊的工作交給了 goctl,第一版本 goctl model 生成主要是網頁版本,後面陸續整合到 goctl 裡了,這給我後續開發帶來了很大的開發效率收益。

  • 展望未來

    goctl 整合了比較多的功能,其基本是以程式碼生成為主,開發規範為輔,goctl 是圍繞 zero-api 為中心做程式碼生成的,因此在將來,zero-api 的建設會成為我們的重心:

    • ast 的改造:替換原有比較重的 antlr4,可以解決很多人安裝 goctl 時 記憶體不夠,系統架構不支援的各種問題,這
    • 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"

如果執行 goctl --version 提示 command not found: goctl 的錯誤,請先排查 $GOBIN 是否在環境變數下。

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 可以列出我們當前已經支援的功能,可能大家在看文件時也沒有專心下來對這塊指令做研究,只是用到一些高頻指令,今天既然是 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 的功能比較豐富,所以難免指令引數比較多,大家在使用時除了看文件外,也善用 --help 這個flag,因為他會告訴你每個指令或者子指令的用法,需要什麼引數,引數型別是字串還是布林,是必填還是可選,切不可自己猜測他應該用什麼 flag,雖然 goctl 是我自己主要維護,其實很多時候,有些指令比較文件,沒有太多 feature 去更新,我也記不住,我也是通過 --help 去檢視功能介紹的

重點演示

goctl completion

檢視 goctl 版本

$ goctl --version
goctl version 1.3.5 darwin/amd64
1.3.5

本節內容僅適合 goctl 版本在 1.3.5及之前的的自動補全設定參考,1.3.5版本及之前僅支援類 Unix 作業系統,不支援 Windows 的自動補全,1.3.5 之後的請跳過此節內容

  1. 執行 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]

根據幫助說明得知,goctl completion 支援通過 --name 傳遞一個引數生成自動補全指令碼檔名,但該引數為非必填,預設不填時為goctl_autocomplete 檔案,其位於 $GOCTLHOME 目錄下。

  1. 執行 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
  1. 檢視當前 shell
$ echo $SHELL                                                  
/bin/zsh
  1. 選擇對應 shell 的指令碼執行,我這裡為 zsh,所以執行指令如下
$ echo PROG=goctl source /Users/keson/.goctl/.auto_complete/zsh/goctl_autocomplete >> ~/.zshrc && source ~/.zshrc
  1. 重啟終端驗證結果
# 鍵入 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

本節內容僅適合 goctl 版本在 1.3.6 及之後的的自動補全設定參考,1.3.6 之前的請跳過此節內容

  1. 如果你是從 1.3.5 升級到 1.3.6 及以後,則需要執行如下指令來清除舊版本自動補全配置,這裡以 zsh 為例子,否則請跳過這一步
# 編輯 ~/.zshrc
$ vim ~/.zshrc
# 找到 PROG=goctl 所在行並刪除
# source
$ source ~/.zshrc && rm .zcompdump*
# 重啟終端
  1. 執行 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.
  1. 檢視當前使用的 shell
$ echo $SHELL                                                  
/bin/zsh
  1. 由於當前使用的 zsh,所以我們來看一下 zsh 的自動補全設定幫助
$ 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

從上文可以看出,根據作業系統的不同,自動補全的設定方式也不一樣,我這裡是 macOS,我們執行一下對應的指令:

$ 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

常見錯誤

  1. goctl Error: unknown flag: --generate-goctl-completion
  2. (eval):1: command not found: _goctl
    按照 1.3.6 自動補全配置重新進行配置

goctl migrate

幫助開發者從1.3.0 之前版本無縫遷移到 1.3.0及後的任意版本,如果使用的 go-zero 版本本身就是 1.3.0 及之後的,則無需做此操作。

為什麼需要遷移?

go-zero 在 1.3.0 版本做了組織變更,即用 zeromicro 替換原來的 tal-tech 組織名稱。

我現在有一個演示專案 awesomemigrate 是用舊版本 goctl 生成的,該專案的 go-zero 的 module 為

module awesomemigrate

go 1.18

require github.com/tal-tech/go-zero v1.2.5

...

假設我們需要將該專案的 go-zero 升級至截止目前最新版本 1.3.3 ,要完成專案從 tal-tech 到 zeromicro 的升級 前需要確保 goctl 版本大於 v1.3.2,然後在執行 goctl 遷移指令執行,如果 goctl 版本小於 v1.3.2,則需要升級。

# 1. 檢視當前 goctl 版本
$ goctl --version
goctl version 1.2.5 darwin/amd64

# 2. 由於 goctl 版本小於 v1.3.2,則需要升級至最新,如果 goctl 版本已經是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. 進入待遷移的專案下,執行遷移指令
$ 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的匹配結果會發現為0:

goctl env

goctl env 主要是用於環境檢測、安裝、環境引數控制等功能,除此之外還可以檢視當前 goctl 的一些環境資訊,以至於使用者在遇到 bug 時可以根據此環境上報當前 goctl 處於的環境。

首先我們看看其使用說明

$ 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 支援環境檢視、引數修改、依賴檢測安裝幾個功能,我們依次來看一下

1. 環境檢視

在不輸入任何 flag 的情況下,則是檢視當前 goctl 環境。

$ 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

以上引數的大概說明為

引數名稱 引數型別 引數說明
GOCTL_OS STRING 當前作業系統,常見值有 darwin、windows、linux 等
GOCTL_ARCH STRING 當前系統架構,常見值有 amd64, 386 等
GOCTL_HOME STRING 預設為 ~/.goctl
GOCTL_DEBUG BOOLEAN 是否開啟 debug 模式,預設為 false,目前暫未使用,主要是 goctl 開發中可能用於控制除錯模式
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版本,如未安裝則為空字串
2. 修改引數

比如我們將 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
3. 依賴檢測/安裝

我們來檢測一下我當前的依賴都是否安裝好,目前依賴檢測內容為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 是快速建立一個 zrpc 服務,protoc 是根據 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 引數,而檢視 help 的時候卻沒有看到介紹?目前我們先這樣理解,我們先拋開 goctl,根據官方 protoc 生成 grpc 程式碼時的指令是什麼?會用到哪些 flag,對於 zrpc 的程式碼生成,你可以理解為 goctl 生成 zrpc 只是在生成 grpc 程式碼指令的基礎上加了 goctl rpc 字首和一些 goctl 生成 zrpc 需要的 flag,而對於 protoc 及 外掛 protoc-gen-go 、 protoc-gen-grpc-go 的相關引數 goctl 只是做繼承,沒有必要顯示的在 help 裡面再描述一遍,後面在分析原始碼時可以給大家詳細講解一些這塊的設計和考慮,接下來我們用一個例子來演示一下,假設我們有一個 greet.proto 檔案,拋開 goctl ,我們生成 grpc 程式碼需要執行的指令如下:

如果不知道 grpc 程式碼是怎麼生成的,這塊建議參考官方文件 https://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 程式碼的指令則應該為

# 這裡多了一個 --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 程式碼時會先對你的環境依賴進行檢測,如果沒有安裝則會自動安裝依賴再生成程式碼。

4. 編輯器外掛

為了提升大家對 zero-api 檔案的編寫效率,我們分別對 intellij 和 vscode 提供了相應的編輯器外掛, intellij 外掛介紹及使用請參考 https://github.com/zeromicro/goctl-intellij, vscode 外掛介紹及使用請參考 https://github.com/zeromicro/goctl-vscode/blob/main/README-cn.md

三、goctl 使用中遇到的問題

goctl 從最初的一個功能 rpc proxy 到當前版本(v1.3.5) 已經擁有13個一級指令和近30個二級指令, 期間 goctl 做了一些調整,而且,gcotl 本身的前進步伐也非常快,他更像是在摸索中前進,朝著更快,更好用的方向發展,因此在迭代的路上,goctl 會顯得有些不穩定,大家興許也遇到很多問題,這裡大概總結一下大家在社群中反饋比較多的一些問題來分享一下。

1. 386 架構上安裝 goctl 失敗!

描述:antlr 生成的原始碼中,沒有對 386 架構的 uint 的邊界值進行很好的處理,導致邊界溢位

修復版本:v1.3.3

2. grpc 到底安裝什麼版本外掛?

描述:熟悉 grpc 的人應該都知道,生成 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 維護的版本(官方文件已經替換為這個),而且必須要安裝protoc-gen-grpc-go 外掛,這樣做的目的是跟著 grpc 官方走,不過使用者不用有太大的心理負擔,一下安裝這麼多依賴,很麻煩,goctl 都已經幫你實現了,你只要使用 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.

描述:產生該原因是因為 go list -json -m 獲取 go module 時拿到的是一個固定值command-line-arguments,該問題已經在 https://github.com/zeromicro/go-zero/pull/1897 進行修復,版本將在 v1.3.6 生效。

4. No help topic 'proto'

描述:該指令在 v1.3.4 已經移除,用 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 的輸出目錄為當前服務 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 程式碼時才有這個問題,目前已經移除了該指令。

8. 為什麼我生成的目錄結構和文件演示不一樣?

對於 goctl rpc protoc 生成 zrpc 程式碼的目錄結構,總的結構上是不會存在差異的,唯一存在差異的是 pb 的輸出目錄,這個取決於你指定的引數來控制,控制 pb 輸出目錄的因素有 go_optgo-grpc_optgo_package ,詳情可參考 《Protocol Buffers: Go Generated Code》。

9. 為什麼我安裝了 goctl 編輯器外掛還是不能高亮

開啟 Goland 的設定,搜尋 FileTypes 設定 api 檔案字尾即可。

專案地址

https://github.com/zeromicro/go-zero

歡迎使用 go-zerostar 支援我們!

微信交流群

關注『微服務實踐』公眾號並點選 交流群 獲取社群群二維碼。

相關文章