LoginSignup
6
2

More than 5 years have passed since last update.

grpc-goのリフレクションについて調べてみた

Posted at

grpc-goのExamplesにあるreflection.Register(s)が何をしているかについて調べたときのメモです。
また、gRPC command line tool(gRPC CLI)をビルドするときにエラーが出たのでその時の対処方法も記載しています。

公式にあるリフレションのチュートリアルがあるので、英語に抵抗がなければそちらを見たほうがいいと思います。

grpc-go/server-reflection-tutorial.md at master · grpc/grpc-go · GitHub


まずは、gRPCサーバのソースです。

grpc-go/main.go at master · grpc/grpc-go · GitHub

package main

import (
    "log"
    "net"

    "golang.org/x/net/context"
    "google.golang.org/grpc"
    pb "google.golang.org/grpc/examples/helloworld/helloworld"
    "google.golang.org/grpc/reflection"
)

const (
    port = ":50051"
)

// server is used to implement helloworld.GreeterServer.
type server struct{}

// SayHello implements helloworld.GreeterServer
func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
    return &pb.HelloReply{Message: "Hello " + in.Name}, nil
}

func main() {
    lis, err := net.Listen("tcp", port)
    if err != nil {
        log.Fatalf("failed to listen: %v", err)
    }
    s := grpc.NewServer()
    pb.RegisterGreeterServer(s, &server{})
    // Register reflection service on gRPC server.
    reflection.Register(s)
    if err := s.Serve(lis); err != nil {
        log.Fatalf("failed to serve: %v", err)
    }
}

この33行目のreflection.Register(s)は、取り外して動かしてもGreeterサービスの呼び出しには何も影響ありません。

では、何をしているのかというと、grpc/reflection.protoに定義されたサービスを追加しています。
このサービスを使うと、公開しているgRPCサーバのサービスの内容を取得することが出来ます。

gRPCのGitリポジトリには、gRPC command line tool(gRPC CLI)というツールがあり、このツールを使えばgRPCサーバがどのようなAPIを提供しているかを見ることができます。

以下はコマンドの例です。

サービス一覧
$ ./grpc_cli ls localhost:50051
grpc.reflection.v1alpha.ServerReflection
helloworld.Greeter
サービスの詳細
$ ./grpc_cli ls localhost:50051 helloworld.Greeter -l
filename: helloworld.proto
package: helloworld;
service Greeter {
  rpc SayHello(helloworld.HelloRequest) returns (helloworld.HelloReply) {}
}
メッセージの型
$ ./grpc_cli type localhost:50051 helloworld.HelloRequest
message HelloRequest {
  string name = 1[json_name = "name"];
}

gRPC command line tool(gRPC CLI)のビルド

先程の例のコマンドgrpc_cliを使うためにはビルドを行う必要があります。

Macでチュートリアルの例に従ってgRPC CLIをビルドしようとしましたが、すんなりいきませんでした。
その時の対応したときのメモです。

まず最初のmake実行時です。

$ git clone https://github.com/grpc/grpc
$ cd grpc
$ make grpc_cli
Package libcares was not found in the pkg-config search path.
Perhaps you should add the directory containing `libcares.pc'
to the PKG_CONFIG_PATH environment variable
No package 'libcares' found

DEPENDENCY ERROR

The target you are trying to run requires an OpenSSL implementation.
Your system doesn't have one, and either the third_party directory
doesn't have it, or your compiler can't build BoringSSL.

Please consult INSTALL to get more information.

If you need information about why these tests failed, run:

  make run_dep_checks

Additionally, since you are in a git clone, you can download the
missing dependencies in third_party by running the following command:

  git submodule update --init

make: *** [stop] Error 1

依存関係に問題があるようです。
エラーメッセージに書かれているgit submodule update --initを実行して再度ビルドします。

$ make grpc_cli
...
test/cpp/util/cli_credentials.cc:21:10: fatal error: 'gflags/gflags.h' file not found

今度はgFlagsが無いようです。
Homebrewにあるのでインストールします。

$ brew install gflags
...
$ cd bins/opt
$ ls
grpc_cli        grpc_cpp_plugin     grpc_node_plugin    grpc_php_plugin     grpc_ruby_plugin
grpc_cli.dSYM       grpc_csharp_plugin  grpc_objective_c_plugin grpc_python_plugin

今度は成功しました。

ドキュメントをよく見ると、ちゃんと説明がありました。orz
Linuxの例もあります。

grpc/command_line_tool.md at master · grpc/grpc · GitHub

6
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2