grpcurl工具学习

grpcurl tools

Posted by alovn on August 1, 2019

grpcurl 工具

Protobuf本身具有反射功能,可以在运行时获取对象都proto文件。gRPC同样也提供了一个名为reflection的反射包,用于为gRPC服务提供查询。gRPC官方提供了一个C++实现都grpc_cli工具,可以用于查询gRPC列表欧调用gRPC方法。但是C++版本的grpc_cli安装比较复杂,推荐使用Go语言实现都grpcurl工具。

安装 grpcurl

grpcurl是Go语言开源社区开发都工具,需要安装:

1
2
go get github.com/fullstorydev/grpcurl
go install github.com/fullstorydev/grpcurl/cmd/grpcurl

启动反射服务

reflection包中只有一个Register函数,用于将grpc.Server注册到反射服务中。 reflection包文档给出了简单都使用方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import (
    "google.golang.org/grpc/reflection"
)
func main() {
    lis, err := net.Listen("tcp", port)
    if err != nil {
        log.Fatalf("failed to listen: %v", err)
    }
    s := grpc.NewServer()
    pb.RegisterHelloServiceServer(s, &server{})

    reflection.Register(s)
    
    if err := s.Serve(lis); err != nil {
        log.Fatalf("failed to serve: %v", err)
    }
}

如果启动了grpc反射服务,那么就可以通过reflection包提供都反射服务查询gRPC服务或调用gRPC方法。

查看 gRPC 服务列表

grpcurl中最常使用都是list命令,用于获取服务或服务方法列表。比如 grpcurl localhost:50051 list 命令 将获取本地50051端口上的grpc服务列表。在使用grpcurl时,需要通过 -cert 和 -key 参数设置公钥和私钥文件,链接启用了 tls 协议都服务。对应没有使用 tls 协议的 grpc 服务,通过 -plaintext 参数忽略 tls 证书都验证过程。如果是 Unix Socket 协议,则需要指定 -unix 参数。

如果没有配置好公钥和私钥文件,也没有忽略证书都验证过程,那么将会遇到类似以下都错误:

1
2
grpcurl localhost:50051 list
Failed to dial target host "localhost:50051": tls: first record does not look like a TLS handshake

如果 grpc 服务正常,但是服务没有启动 reflection 反射服务,将会遇到以下错误:

1
2
grpcurl --plaintext localhost:50051 list
Failed to list services: server does not support the reflection API

假设 grpc 服务已经启动了 reflection 反射服务,服务的 protobuf 文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
syntax = "proto3";
package hello;

message HelloRequest {
string greeting = 1;
}

message HelloResponse {
string reply = 1;
repeated int32 number=4;
}

service HelloService {
rpc SayHello(HelloRequest) returns (HelloResponse){}
}

用 grpcurl 的 list 命令查看服务列表时会看到以下都输出:

1
2
3
$ grpcurl --plaintext localhost:50051 list
grpc.reflection.v1alpha.ServerReflection
hello.HelloService

其中 hello.HelloService 是在 protobuf 文件中定义都服务。而 ServerReflection 服务则是 reflection 包注册都反射服务。通过 ServerReflection 服务可以查询包括本身在内都全部 gRPC 服务信息。

查询服务的方法列表

继续使用 list 子命令还可以查看 HelloService 服务都方法列表:

1
2
$ grpcurl -plaintext localhost:50051 list hello.HelloService
hello.HelloService.SayHello

从输出可以看出 HelloService 提供了 SayHello 方法,和 protobuf 文件定义是一致的。 如果还想了解方法的细节,可以使用 grpcurl 提供都 describe 子命令查看更详细的描述信息:

1
2
3
4
5
6
7
8
9
$ grpcurl -plaintext localhost:50051 describe hello.HelloService
hello.HelloService is a service:
service HelloService {
    rpc SayHello ( .hello.HelloRequest ) returns ( .hello.HelloResponse );
}

$ grpcurl -plaintext localhost:50051 describe hello.HelloService.SayHello
hello.HelloService.SayHello is a method:
rpc SayHello ( .hello.HelloRequest ) returns ( .hello.HelloResponse );

调用 gRPC 方法

下面通过命令 -d 参数传入一个 json 字符串作为输入参数,调用都是 HelloService 的 SayHello 方法:

1
2
3
4
5
6
7
8
$ grpcurl -plaintext -d '{"greeting": "World"}' localhost:50051 hello.HelloService/SayHello
{
    "reply": "Hello World",
    "number": [
        1,
        2
    ]
}

通过grpcurl工具,我们可以在没有服务端代码的环境下, 仍然可以获取grpc 方法列表、测试gRPC服务。

以上gRPC服务代码可参考 grpc-demo