grpcurl是一个命令行工具,使用它可以在命令行中访问gRPC服务,就像使用curl访问http服务一样。

准备

在gRPC服务中注册reflection服务:

gRPC服务是使用Protobuf(PB)协议的,而PB提供了在运行时获取Proto定义信息的反射功能。grpc-go中的”google.golang.org/grpc/reflection”包就对这个反射功能提供了支持。
这里以grpc-go官方的helloword为例,代码结构如下:

  1. grpc-hello
  2. ├── go.mod
  3. ├── go.sum
  4. ├── main.go
  5. └── proto
  6. ├── doc.go
  7. ├── helloworld.pb.go
  8. └── helloworld.proto

helloworld.proto:

  1. syntax = "proto3";
  2. package proto;
  3. // The greeting service definition.
  4. service Greeter {
  5. // Sends a greeting
  6. rpc SayHello (HelloRequest) returns (HelloReply) {}
  7. }
  8. // The request message containing the user's name.
  9. message HelloRequest {
  10. string name = 1;
  11. }
  12. // The response message containing the greetings
  13. message HelloReply {
  14. string message = 1;
  15. }

main.go:

  1. package main
  2. import "fmt"
  3. import "log"
  4. import "net"
  5. import "context"
  6. import "grpc-hello/proto"
  7. import "google.golang.org/grpc"
  8. import "google.golang.org/grpc/reflection"
  9. func main() {
  10. lis, err := net.Listen("tcp", ":8080")
  11. if err != nil {
  12. log.Fatalf("failed to listen: %v", err)
  13. }
  14. server := grpc.NewServer()
  15. // 注册grpcurl所需的reflection服务
  16. reflection.Register(server)
  17. // 注册业务服务
  18. proto.RegisterGreeterServer(server, &greeter{})
  19. if err := server.Serve(lis); err != nil {
  20. log.Fatalf("failed to serve: %v", err)
  21. }
  22. }
  23. type greeter struct {
  24. }
  25. func (*greeter) SayHello(ctx context.Context, req *proto.HelloRequest) (*proto.HelloReply, error) {
  26. fmt.Println(req)
  27. reply := &proto.HelloReply{Message: "hello"}
  28. return reply, nil
  29. }

在main.go的第19行,使用reflection.Register(server)注册了reflection服务。

安装和使用

安装grpcurl:

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

使用示例:

  • 查看服务列表:

    1. $ grpcurl -plaintext 127.0.0.1:8080 list
    2. grpc.reflection.v1alpha.ServerReflection
    3. proto.Greeter
  • 查看某个服务的方法列表:

    1. $ grpcurl -plaintext 127.0.0.1:8080 list proto.Greeter
    2. proto.Greeter.SayHello
  • 查看方法定义:

    1. $ grpcurl -plaintext 127.0.0.1:8080 describe proto.Greeter.SayHello
    2. proto.Greeter.SayHello is a method:
    3. rpc SayHello ( .proto.HelloRequest ) returns ( .proto.HelloReply );
  • 查看请求参数:

    1. $ grpcurl -plaintext 127.0.0.1:8080 describe proto.HelloRequest
    2. proto.HelloRequest is a message:
    3. message HelloRequest {
    4. string name = 1;
    5. }
  • 调用服务,参数传json即可:

    1. $ grpcurl -d '{"name": "abc"}' -plaintext 127.0.0.1:8080 proto.Greeter.SayHello
    2. {
    3. "message": "hello"
    4. }

    总结

    grpcurl这个工具从使用上十分简单,查看服务信息基本上类似展示的proto文件的内容,调用服务这个功能还是很实用的,可以整合到k8s的Pod镜像中,用于在k8s集群内部简单测试gRPC服务。