关于 grpcurl
grpcurl 提供了一个命令行界面与 gRPC 服务器交互,操作方式类似于 HTTP 工具 curl。支持列举服务、描述方法签名、发送请求等功能,可直接与 gRPC 远程服务器通信和调试。
主要功能
- 01列举 gRPC 服务器上的可用服务和方法
- 02查看服务方法的详细描述和参数签名
- 03向 gRPC 端点发送请求并获取响应
适用场景
- 01调试和测试 gRPC API 服务的功能和响应
- 02在开发环境中与 gRPC 远程服务器交互
- 03验证 gRPC 服务的定义和可用性
安装
选择你的系统或包管理器,复制命令到终端运行。
安装完成后运行grpcurl --version确认安装成功。
命令示例
常用命令按使用顺序排列。
详细介绍
gRPCurl
grpcurl 是一款命令行工具,可用于与 gRPC 服务交互。它基本上就是面向 gRPC 服务的 curl。
该工具的主要用途是在命令行中调用 gRPC 服务上的 RPC 方法。gRPC 服务在线路上传输二进制编码的数据
(协议缓冲区,简称“protobuf”)。
因此,基本上无法使用常规的 curl 与它们交互
(当然,不支持 HTTP/2 的旧版 curl 也完全无法胜任)。
此程序接受 JSON 编码的消息,对用户和脚本都更加友好。
使用此工具还可以浏览 gRPC 服务的架构:既可以查询支持服务反射的服务,
也可以读取 proto 源文件,或加载已编译的“protoset”文件(包含编码后的文件描述符 proto)。
事实上,该工具将 JSON 请求数据转换为二进制编码 protobuf 的方式正是借助同一份架构。因此,如果要交互的服务不支持
反射,你就需要提供定义该服务的 proto 源文件,或提供 grpcurl 可以使用的 protoset 文件。
此仓库还提供了一个库包 github.com/fullstorydev/grpcurl,其中包含用于简化其他命令行工具构建的函数,这些工具可动态调用 gRPC 端点。
此代码也是展示如何使用 protoreflect 库的各种包的优秀示例,并展示了这些包的功能。
另请参阅 GopherCon 2018 上关于 grpcurl 的演讲。
功能
grpcurl 支持各种 RPC 方法,包括流式方法。你甚至可以通过在交互式终端中运行 grpcurl 并将 stdin 用作请求正文,以交互方式操作双向流式方法!
grpcurl 同时支持安全/TLS 服务和纯文本服务(即无 TLS),并提供多种 TLS 配置选项。它还支持双向 TLS,在这种模式下,客户端必须提供客户端证书。
如上所述,如果服务支持反射服务,grpcurl 就能无缝工作。如果不支持,你可以向 grpcurl 提供 .proto 源文件,或提供 protoset 文件(包含由 protoc 生成的已编译描述符)。
安装
二进制文件
从 releases 页面下载二进制文件。
Homebrew(macOS)
在 macOS 上,可通过 Homebrew 获取 grpcurl:
brew install grpcurl
Docker
对于支持 Docker 的平台,你可以下载镜像来运行 grpcurl:
# Download image
docker pull ghcr.io/fullstorydev/grpcurl:latest
# Run the tool
docker run ghcr.io/fullstorydev/grpcurl api.grpc.me:443 list
请注意,使用 docker 时有一些需要注意的地方:
- 如果需要与监听在主机环回网络上的服务交互,必须将主机指定为
host.docker.internal,而不是localhost(适用于 Mac 或 Windows);_或者_让容器使用主机网络,添加-network="host"(仅限 Linux)。 - 如果需要提供 proto 源文件或描述符集,必须将包含这些文件的文件夹挂载为卷(
-v $(pwd):/protos),并相应地将导入路径调整为容器内的路径。 - 如果想通过 stdin 提供请求消息并使用
-d @选项,则需要在 docker 命令中使用-i标志。
其他软件包
由于第三方提供了为 grpcurl 创建的安装配方和软件包,因此还有许多其他安装方式。这些方式适用于多种环境,包括 Windows 和众多 Linux 发行版。
你可以在 repology.org 查看关于 grpcurl 的更多详情和其他软件包的完整列表:
https://repology.org/project/grpcurl/information
Snap
你可以使用 snap 软件包安装 grpcurl:
snap install grpcurl
从源代码安装
如果你已安装 Go SDK,可以使用 go
工具安装 grpcurl:
go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest
这会将命令安装到 $GOPATH 环境变量所指向位置的 bin 子文件夹中。(如果未设置 GOPATH 环境变量,默认安装位置为 $HOME/go/bin。)如果此目录已在你的 $PATH 中,就可以直接使用了。
如果你已将此仓库拉取到 $GOPATH 之外的位置,并且想从源代码构建,可以 cd 进入仓库,然后运行 make install。
如果遇到编译错误,且使用的 Go SDK 版本早于 1.13,则 grpcurl 的依赖项可能已过时。你可以运行 make updatedeps 更新依赖项。或者,如果你使用的是 Go 1.11 或 1.12,可以在上述命令前加上 GO111MODULE=on,这样也会使用正确版本的依赖项进行构建(而不是使用 $GOPATH 中可能已有的版本)。
用法
该工具的用法文档介绍了众多选项:
grpcurl -help
在下面的各个部分中,你会看到许多展示如何使用
grpcurl 的示例。
调用 RPC
使用 grpcurl 调用受信任服务上的 RPC(例如,使用 TLS,且不使用自签名密钥或自定义 CA),无需客户端证书,并且支持服务器反射,是最简单的用法。以下最简调用会发送一个空请求体:
grpcurl grpc.server.com:443 my.custom.server.Service/Method
# no TLS
grpcurl -plaintext grpc.server.com:80 my.custom.server.Service/Method
要发送非空请求,请使用 -d 参数。请注意,所有参数都必须放在服务地址和方法名之前:
grpcurl -d '{"id": 1234, "tags": ["foo","bar"]}' \
grpc.server.com:443 my.custom.server.Service/Method
如示例所示,提供的请求体必须采用 JSON 格式。请求体会先经过解析,然后以 protobuf 二进制格式传输到服务端。
如果想在命令管道中使用 grpcurl,例如使用 jq 创建请求体,可以使用 -d @,它会告诉 grpcurl 从标准输入读取实际请求体:
grpcurl -d @ grpc.server.com:443 my.custom.server.Service/Method <<EOM
{
"id": 1234,
"tags": [
"foo",
"bar"
]
}
EOM
为请求添加标头/元数据
可以通过 -H name:value 命令行选项为 RPC 请求添加标头/元数据。也可以用类似方式添加多个标头。
示例:
grpcurl -H header1:value1 -H header2:value2 -d '{"id": 1234, "tags": ["foo","bar"]}' grpc.server.com:443 my.custom.server.Service/Method
如需更多用法指南,请通过 grpcurl -help 查看帮助文档。
列出服务
要列出服务端公开的所有服务,请使用 "list" 动词。使用 .proto 源文件或 protoset 文件,而不是服务器反射时,此命令会列出源文件或 protoset 文件中定义的所有服务。
# Server supports reflection
grpcurl localhost:8787 list
# Using compiled protoset files
grpcurl -protoset my-protos.bin list
# Using proto sources
grpcurl -import-path ../protos -proto my-stuff.proto list
# Export proto files (use -proto-out-dir to specify the output directory)
grpcurl -plaintext -proto-out-dir "out_protos" "localhost:8787" describe my.custom.server.Service
# Export protoset file (use -protoset-out to specify the output file)
grpcurl -plaintext -protoset-out "out.protoset" "localhost:8787" describe my.custom.server.Service
"list" 动词还可以列出特定服务中的所有方法:
grpcurl localhost:8787 list my.custom.server.Service
描述元素
"describe" 动词会打印服务端已知或给定 protoset 文件中存在的任何符号的类型。它还会以 proto 源代码片段的形式打印该符号的描述。输出不一定是定义该元素的原始源代码,但内容等效。
# Server supports reflection
grpcurl localhost:8787 describe my.custom.server.Service.MethodOne
# Using compiled protoset files
grpcurl -protoset my-protos.bin describe my.custom.server.Service.MethodOne
# Using proto sources
grpcurl -import-path ../protos -proto my-stuff.proto describe my.custom.server.Service.MethodOne
描述符来源
grpcurl 工具可以使用多种描述符来源。grpcurl 需要这些描述符来理解 RPC 架构、将输入转换为 protobuf 二进制格式,以及将响应从二进制格式转换为文本。以下各部分将介绍支持的来源,以及使用它们所需的命令行标志。
服务反射
如果没有其他命令行标志,grpcurl 将尝试使用服务反射。
此处提供了设置服务反射的示例。
使用反射时,即使执行“list”和“describe”操作,也必须提供服务地址(host:port 或 Unix 套接字路径),这样 grpcurl 才能连接到服务并向其请求描述符。
Proto 源文件
对于不支持反射的服务,可以使用 .proto 源文件运行 grpcurl。
除了使用 -proto 标志指定相关的 proto 源文件外,你可能还需要提供 -import-path 标志,告知 grpcurl 可以从哪些文件夹导入依赖项。
与使用 protoc 编译时一样,你无需为 protoc 附带的标准 proto 文件所在位置提供导入路径(这些文件包含包定义为 google.protobuf 的各种“众所周知类型”)。grpcurl“已知”这些文件,因为其二进制文件内置了这些文件描述符的快照。
使用 proto 源文件时,执行“list”和“describe”操作可以省略服务地址(host:port 或 Unix 套接字路径),因为这些操作只需查阅 proto 源文件。
Protoset 文件
你也可以在 grpcurl 中使用已编译的 protoset 文件。如果你要编写脚本调用 grpcurl,并且需要在多次调用中重复使用相同的 proto 源文件,那么使用 protoset 文件会获得更好的性能(因为每次调用都可以跳过解析和编译步骤)。
Protoset 文件包含二进制编码的 google.protobuf.FileDescriptorSet proto。要创建 protoset 文件,请使用定义该服务的 *.proto 文件调用 protoc:
protoc --proto_path=. \
--descriptor_set_out=myservice.protoset \
--include_imports \
my/custom/server/service.proto
--descriptor_set_out 参数用于告知 protoc 生成 protoset,而 --include_imports 参数则是必要的,它能确保 protoset 包含 grpcurl 处理和理解该架构所需的所有内容。
使用 protoset 文件时,执行“list”和“describe”操作可以省略服务地址(host:port 或 Unix 套接字路径),因为这些操作只需查阅 protoset 文件。