使用 dubbogo-cli 工具
1. 安裝
dubbogo-cli 是 Apache/dubbo-go 生態系統的子項目,它為開發人員提供了便捷的功能,例如應用程式範本建立、工具安裝和介面除錯,以提高使用者研發效率。
執行以下指令將 dubbogo-cli 安裝到 $GOPATH/bin
go install github.com/dubbogo/dubbogo-cli@latest
2. 功能概述
dubbogo-cli 支援以下功能
應用程式範本建立
dubbogo-cli newApp.
在目前目錄中建立應用程式範本
Demo 建立
dubbogo-cli newDemo.
在目前目錄中建立一個 RPC 範例,包含客戶端和伺服器端
編譯和除錯工具安裝
dubbogo-cli install all
一鍵安裝以下工具到 $GOPATH/bin
-protoc-gen-go-triple
Compilation for triple protocol interface
imports-formatter
用於整理程式碼匯入區塊。
檢視 dubbo-go 應用程式註冊資訊
檢視 Zookeeper 上的註冊資訊以取得介面和方法列表
$ dubbogo-cli show --r zookeeper --h 127.0.0.1:2181 interface: com.dubbogo.pixiu.UserService methods: [CreateUser, GetUserByCode, GetUserByName, GetUserByNameAndAge, GetUserTimeout, UpdateUser, UpdateUserByName]
檢視 Nacos 上的註冊資訊 [功能開發中]
檢視 Istio 的註冊資訊 [功能開發中]
除錯 Dubbo 協定介面
除錯 Triple 協定介面
3. 功能細節
3.1 Demo 應用程式介紹
3.1.1 Demo 建立
dubbogo-cli newDemo.
在目前目錄中建立一個 demo,包含客戶端和伺服器。該 demo 展示了基於一組介面完成 RPC 呼叫。
此 Demo 使用直連模式,不依賴註冊中心。服務端將服務暴露在本地 20000 端口,客戶端發起調用。
.
├── api
│ ├── samples_api.pb.go
│ ├── samples_api.proto
│ └── samples_api_triple.pb.go
├── go-client
│ ├── cmd
│ │ └── client.go
│ └── conf
│ └── dubbogo.yaml
├── go-server
│ ├── cmd
│ │ └── server.go
│ └── conf
│ └── dubbogo.yaml
└── go.mod
3.1.2 執行 Demo
啟動服務端
$ cd go-server/cmd
$ go run .
另一個終端開啟客戶端
$ go mod tidy
$ cd go-client/cmd
$ go run .
可以看到打印日誌
INFO cmd/client.go:49 client response result: name:"Hello laurence" id:"12345" age:21
3.2 應用模板介紹
3.2.1 應用模板創建
dubbogo-cli newApp.
在目前目錄中建立應用程式範本
.
├── Makefile
├── api
│ ├── api.pb.go
│ ├── api.proto
│ └── api_triple.pb.go
├──build
│ └── Dockerfile
├── chart
│ ├── app
│ │ ├── Chart.yaml
│ │ ├── templates
│ │ │ ├── _helpers.tpl
│ │ │ ├── deployment.yaml
│ │ │ ├── service.yaml
│ │ │ └── serviceaccount.yaml
│ │ └── values.yaml
│ └── nacos_env
│ ├── Chart.yaml
│ ├── templates
│ │ ├── _helpers.tpl
│ │ ├── deployment.yaml
│ │ └── service.yaml
│ └── values.yaml
├── cmd
│ └── app.go
├── conf
│ └── dubbogo.yaml
├── go.mod
├── go.sum
└── pkg
└── service
└── service.go
3.2.2 應用模板介紹
生成的專案包含幾個目錄
api:放置介面檔案:proto 檔案和生成的 .pb.go 檔案
build:放置鏡像構建相關檔案
Chart:放置用於發佈的 chart 倉庫,基礎環境 chart 倉庫:nacos、mesh(開發中)
cmd:程式入口
conf:框架配置
pkg/service:RPC 服務實現
Makefile
- 鏡像、helm 部署名稱
- IMAGE = $(your_repo)/$(namespace)/$(image_name) TAG = 1.0.0
HELM_INSTALL_NAME = dubbo-go-app,helm 安裝名稱,用於 helm install/uninstall 命令。
- 提供如下腳本
- make build # 打包鏡像並推送
make buildx-publish # arm 架構本地打包 amd64 鏡像並推送,依賴 docker buildx
make deploy # 通過 helm 發佈應用
make remove # 刪除已發佈的 helm 應用
make proto-gen # 生成 api 下的 pb.go 檔案
使用應用模板的開發流程
依賴環境:make、go、helm、kubectl、docker
- 通過 dubbogo-cli 生成模板
- 修改 api/api.proto
- make proto-gen
- 開發介面
- 修改 makefile 中的 IMAGE 鏡像名稱和 HELM_INSTALL_NAME 發佈名稱
- 製作鏡像並推送
- 修改 chart/app/values 中與部署相關的 value 配置,重點關注 image 部分。
image:
repository: $(your_repo)/$(namespace)/$(image_name)
pullPolicy: Always
tag: "1.0.0"
- make deploy,使用 helm 發佈應用。
3.3 使用 gRPC 協定除錯 dubbo-go 應用
3.3.1 簡介
grpc_cli 工具是 gRPC 生態系統用於除錯服務的工具,它可以在伺服器端開啟[反射服務](https://github.com/grpc/grpc/blob/master/doc/server-reflection.md)的前提下,取得服務的 proto 檔案、服務名稱、方法名稱、參數列表,並發起 gRPC 調用。
Triple 協定相容 gRPC 生態,預設開啟了 gRPC 反射服務,因此可以直接使用 grpc_cli 除錯 triple 服務。
3.3.2 安裝 grpc_cli
後續安裝將由 dubbogo-cli 完成,目前需要用戶手動安裝
參考 grpc_cli 文件
3.3.3 使用 grpc_cli 除錯 Triple 服務
- 查看 triple 服務的介面定義
$ grpc_cli ls localhost:20001 -l
filename: helloworld.proto
package: org.apache.dubbo.quickstart.samples;
service UserProvider {
rpc SayHello(org.apache.dubbo.quickstart.samples.HelloRequest) returns (org.apache.dubbo.quickstart.samples.User) {}
rpc SayHelloStream(stream org.apache.dubbo.quickstart.samples.HelloRequest) returns (stream org.apache.dubbo.quickstart.samples.User) {}
}
- 查看請求參數類型
例如,開發者想要測試上述 port 的 SayHello 方法,並嘗試取得 HelloRequest 的具體定義,則需要執行以下命令查看對應參數的定義。
$ grpc_cli type localhost:20001 org.apache.dubbo.quickstart.samples.HelloRequest
message HelloRequest {
string name = 1 [json_name = "name"];
}
- 請求介面
了解請求參數的具體類型後,即可發起調用測試對應的服務。查看返回值是否符合預期。
$ grpc_cli call localhost:20001 SayHello "name: 'laurence'"
connecting to localhost:20001
name: "Hello Laurence"
id: "12345"
age: 21
Received trailing metadata from server:
accept-encoding: identity, gzip
adaptive-service.inflight : 0
adaptive-service. remaining : 50
grpc-accept-encoding : identity,deflate,gzip
Rpc succeeded with OK status
3.4 使用 Dubbo 協定除錯 dubbo-go 應用
3.4.1 開啟 Dubbo 服務端
範例:user.go
func (u *UserProvider) GetUser(ctx context.Context, userStruct *CallUserStruct) (*User, error) {
fmt.Printf("=========================\nreq:%#v\n", userStruct)
rsp := User{"A002", "Alex Stocks", 18, userStruct.SubInfo}
fmt.Printf("========================\nrsp:%#v\n", rsp)
return &rsp, nil
}
服務端開啟一個名為 GetUser 的服務,傳入一個 CallUserStruct 參數,返回一個 User 參數 CallUserStruct 參數定義
type CallUserStruct struct {
ID string
Male bool
SubInfo SubInfo // nested substructure
}
func (cs CallUserStruct) JavaClassName() string {
return "com.ikurento.user.CallUserStruct"
}
type SubInfo struct {
SubID string
SubMale bool
SubAge int
}
func (s SubInfo) JavaClassName() string {
return "com.ikurento.user.SubInfo"
}
User 結構定義
type User struct {
Id string
name string
Age int32
SubInfo SubInfo // Nest the above substructure SubInfo
}
func (u *User) JavaClassName() string {
return "com.ikurento.user.User"
}
啟動服務
cd server`
`source builddev.sh`
`go run.
3.4.2 定義請求體(適配序列化協定)
請求體定義為 json 檔案,約定的鍵值均為字串。鍵對應 Go 語言 struct 的欄位名稱,例如 “ID” 和 “Name”,值對應 “type@val”。其中 type 支援 string int bool time,val 以字串初始化。如果只填寫 type,則初始化為零值。約定每個 struct 都必須有一個 JavaClassName 欄位,必須與服務端嚴格對應。
請參閱 userCall.json
{
"ID": "string@A000",
"Male": "bool@true",
"SubInfo": {
"SubID": "string@A001",
"SubMale": "bool@false",
"SubAge": "int@18",
"JavaClassName": "string@com.ikurento.user.SubInfo"
},
"JavaClassName": "string@com.ikurento.user.CallUserStruct"
}
userCall.json 定義了參數 CallUserStruct 和子結構 SubInfo 的結構,並賦予請求參數值。
同樣地,user.json 不需要賦予初始值作為返回值,但 JavaClassName 欄位必須與伺服器端嚴格對應。
{
"ID": "string",
"Name": "string",
"Age": "int",
"JavaClassName": "string@com.ikurento.user.User",
"SubInfo": {
"SubID": "string",
"SubMale": "bool",
"SubAge": "int",
"JavaClassName": "string@com.ikurento.user.SubInfo"
}
}
3.4.3 除錯埠
./dubbo-go-cli -h=localhost -p=20001 -proto=dubbo -i=com.ikurento.user.UserProvider -method=GetUser -sendObj="./userCall.json" -recvObj="./user .json"
列印結果
2020/10/26 20:47:45 Created pkg:
2020/10/26 20:47:45 &{ID:A000 Male:true SubInfo:0xc00006ea20 JavaClassName:com.ikurento.user.CallUserStruct}
2020/10/26 20:47:45 SubInfo:
2020/10/26 20:47:45 &{SubID:A001 SubMale:false SubAge:18 JavaClassName:com.ikurento.user.SubInfo}
2020/10/26 20:47:45 Created pkg:
2020/10/26 20:47:45 &{ID: Name: Age:0 JavaClassName:com.ikurento.user.User SubInfo:0xc00006ec90}
2020/10/26 20:47:45 SubInfo:
2020/10/26 20:47:45 &{SubID: SubMale:false SubAge:0 JavaClassName:com.ikurento.user.SubInfo}
2020/10/26 20:47:45 connected to localhost:20001!
2020/10/26 20:47:45 try calling interface: com.ikurento.user.UserProvider.GetUser
2020/10/26 20:47:45 with protocol: dubbo
2020/10/26 20:47:45 After 3ms , Got Rsp:
2020/10/26 20:47:45 &{ID:A002 Name:Alex Stocks Age:18 JavaClassName: SubInfo:0xc0001241b0}
2020/10/26 20:47:45 SubInfo:
2020/10/26 20:47:45 &{SubID:A001 SubMale:false SubAge:18 JavaClassName:}```
您可以看到詳細的請求主體賦值,以及返回的結果和耗時。支援巢狀結構。
列印伺服器端結果
=========================
req:&main.CallUserStruct{ID:"A000", Male:true, SubInfo:main.SubInfo{SubID:"A001", SubMale:false, SubAge:18}}
=========================
可以看出,已接收到來自 cli 的數據。