grpcurl工具
grpcurl工具
Protobuf本身具有反射功能,可以在運行時獲取對象的Proto文件。gRPC同樣也提供了一個名為reflection的反射包,用于為gRPC服務提供查詢。gRPC官方提供了一個C++實現的grpc_cli工具,可以用于查詢gRPC列表或調用gRPC方法。但是C++版本的grpc_cli安裝比較復雜,我們推薦用純Go語言實現的grpcurl工具。本節將簡要介紹grpcurl工具的用法。
啟動反射服務
reflection包中只有一個Register函數,用于將grpc.Server注冊到反射服務中。reflection包文檔給出了簡單的使用方法:
import (
"google.golang.org/grpc/reflection"
)
func main() {
s := grpc.NewServer()
pb.RegisterYourOwnServer(s, &server{})
// Register reflection service on gRPC server.
reflection.Register(s)
s.Serve(lis)
}
如果啟動了gprc反射服務,那么就可以通過reflection包提供的反射服務查詢gRPC服務或調用gRPC方法。
查看服務列表
grpcurl是Go語言開源社區開發的工具,需要手工安裝:
$ go get github.com/fullstorydev/grpcurl
$ go install github.com/fullstorydev/grpcurl/cmd/grpcurl
grpcurl中最常使用的是list命令,用于獲取服務或服務方法的列表。比如grpcurl localhost:1234 list命令將獲取本地1234端口上的grpc服務的列表。在使用grpcurl時,需要通過-cert和-key參數設置公鑰和私鑰文件,鏈接啟用了tls協議的服務。對于沒有沒用tls協議的grpc服務,通過-plaintext參數忽略tls證書的驗證過程。如果是Unix Socket協議,則需要指定-unix參數。
如果沒有配置好公鑰和私鑰文件,也沒有忽略證書的驗證過程,那么將會遇到類似以下的錯誤:
$ grpcurl localhost:1234 list
>> Failed to dial target host "localhost:1234": tls: first record does not look like a TLS handshake
如果grpc服務正常,但是服務沒有啟動reflection反射服務,將會遇到以下錯誤:
$ grpcurl -plaintext localhost:1234 list
>> Failed to list services: server does not support the reflection API
假設grpc服務已經啟動了reflection反射服務,服務的Protobuf文件如下:
syntax = "proto3";
package HelloService;
message String {
string value = 1;
}
service HelloService {
rpc Hello (String) returns (String);
rpc Channel (stream String) returns (stream String);
}
grpcurl用list命令查看服務列表時將看到以下輸出:
$ grpcurl -plaintext localhost:1234 list
>> HelloService.HelloService
>> grpc.reflection.v1alpha.ServerReflection
其中HelloService.HelloService是在protobuf文件定義的服務。而ServerReflection服務則是reflection包注冊的反射服務。通過ServerReflection服務可以查詢包括本身在內的全部gRPC服務信息。
服務的方法列表
繼續使用list子命令還可以查看HelloService服務的方法列表:
$ grpcurl -plaintext localhost:1234 list HelloService.HelloService
>> Channel
>> Hello
從輸出可以看到HelloService服務提供了Channel和Hello兩個方法,和Protobuf文件的定義是一致的。
如果還想了解方法的細節,可以使用grpcurl提供的describe子命令查看更詳細的描述信息:
$ grpcurl -plaintext localhost:1234 describe HelloService.HelloService
HelloService.HelloService is a service:
{
"name": "HelloService",
"method": [
{
"name": "Hello",
"inputType": ".HelloService.String",
"outputType": ".HelloService.String",
"options": {
}
},
{
"name": "Channel",
"inputType": ".HelloService.String",
"outputType": ".HelloService.String",
"options": {
},
"clientStreaming": true,
"serverStreaming": true
}
],
"options": {
}
}
獲取類型信息
在獲取到方法的參數和返回值類型之后,還可以繼續查看類型的信息。下面是用describe命令查看參數HelloService.String類型的信息:
$ grpcurl -plaintext localhost:1234 describe HelloService.String
HelloService.String is a message:
{
"name": "String",
"field": [
{
"name": "value",
"number": 1,
"label": "LABEL_OPTIONAL",
"type": "TYPE_STRING",
"options": {
},
"jsonName": "value"
}
],
"options": {
}
}
json信息對應HelloService.String類型在Protobuf中的定義如下:
message String {
string value = 1;
}
輸出的json數據只不過是Protobuf文件的另一種表示形式。
調用方法
在獲取gRPC服務的詳細信息之后就可以json調用gRPC方法了。
下面命令通過-d參數傳入一個json字符串作為輸入參數,調用的是HelloService服務的Hello方法:
$ grpcurl -plaintext -d '{"value": "gopher"}' \
localhost:1234 HelloService.HelloService/Hello
{
"value": "hello:gopher"
}
如果-d參數是@則表示從標準輸入讀取json輸入參數,這一般用于比較輸入復雜的json數據,也可以用于測試流方法。
下面命令是鏈接Channel流方法,通過從標準輸入讀取輸入流參數:
$ grpcurl -plaintext -d @ localhost:1234 HelloService.HelloService/Channel
{"value": "gopher"}
{
"value": "hello:gopher"
}
{"value": "wasm"}
{
"value": "hello:wasm"
}
通過grpcurl工具,我們可以在沒有客戶端代碼的環境下測試gRPC服務。
Songzhibin

浙公網安備 33010602011771號