gRPC Quick Start

公式が用意してくれていたので倣う。

準備

# Protocol Buffers $ brew install protobuf # Go plugins $ go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.26 $ go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.1 $ echo 'export PATH="$PATH:$(go env GOPATH)/bin"' >> ~/.zshrc # Get the example code $ git clone -b v1.41.0 https://github.com/grpc/grpc-go $ cd grpc-go/examples/helloworld

サーバーを起動

$ go run greeter_server/main.go 2021/12/07 17:33:21 server listening at [::]:50051

クライアントを起動

別ターミナルで

$ go run greeter_client/main.go 2021/12/07 17:33:57 Greeting: Hello world # サーバー側ログ 2021/12/07 17:33:57 Received: world

おめでとう

これでサーバークライアント型の挨拶アプリケーションが動きました。

gRPCサービスを更新してみる

これは作り替えてみるセクションです。gRPはProtocol Buffersで動いてるので.protoファイルを書き換えていきますもっと詳しく知りたかったら https://grpc.io/docs/languages/go/basics/ を見てね。

例えば今はHelloRequestを受け取りHelloReplyを返すSayHello()というRPCメソッドがあり、以下のように定義されます。

// The greeting service definition. service Greeter { // Sends a greeting rpc SayHello (HelloRequest) returns (HelloReply) {} } // The request message containing the user's name. message HelloRequest { string name = 1; } // The response message containing the greetings message HelloReply { string message = 1; }

実際には helloworld/helloworld.proto に記述されています。

では helloworld.proto を開き、SayHelloAgain()メソッドを定義してみましょう。

service Greeter { // Sends a greeting rpc SayHello (HelloRequest) returns (HelloReply) {} // --- ここから追加 // Sends another greeting rpc SayHelloAgain (HelloRequest) returns (HelloReply) {} // --- ここまで }

変更を加えたら忘れずに保存してください。

gRPCコードを再生成

変更した.protoファイルに基づきリコンパイルしgRPCコードを再生成します。

examples/helloworld ディレクトリ内で以下のコードを実行します。

$ protoc --go_out=. --go_opt=paths=source_relative \ --go-grpc_out=. --go-grpc_opt=paths=source_relative \ helloworld/helloworld.proto

これにより helloworld/helloworld.pb.go と helloworld/helloworld_grpc.pb.go が生成されます。これらは入力やシリアル化、所得のためのコードとサーバーとクライアントのコードが記述されています。

サーバー/クライアントのコードを更新

1. サーバーのコードを更新します。

greeter_server/main.go を開き以下を追加してください。

func (s *server) SayHelloAgain(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { return &pb.HelloReply{Message: "Hello again " + in.GetName()}, nil }
2. クライアント側のコードも更新します。

greeter_client/main.go を開いてmain()関数の最後に追記してください。

r, err = c.SayHelloAgain(ctx, &pb.HelloRequest{Name: name}) if err != nil { log.Fatalf("could not greet: %v", err) } log.Printf("Greeting: %s", r.GetMessage())

忘れずに保存しましょう。

起動

まずはサーバーを起動しましょう。

$ go run greeter_server/main.go 2021/12/07 18:10:16 server listening at [::]:50051

次に別ターミナルでクライアントを起動します。今回はコマンド引数を渡します。

$ go run greeter_client/main.go Alice 2021/12/07 18:10:31 Greeting: Hello Alice 2021/12/07 18:10:31 Greeting: Hello again Alice

2度挨拶が返答されていますね。成功です。

🏝️
これをminikube上のpodで動かせたらいいね。