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服務。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM