はじめに
マイクロサービス間の通信に使われると話題(相当流行遅れ)のgRPCを触ってみた。
実践
protocol plugin をインストールする。
$ go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28 $ go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2
練習用リポジトリをクローンする。
$ git clone -b v1.50.0 --depth 1 https://github.com/grpc/grpc-go
練習用ディレクトリに移動しサーバーを立ち上げ、ターミナルの別タブでクライアントからリクエストを送信する。
$ cd grpc-go/examples/helloworld
# サーバー $ go run greeter_server/main.go 2023/01/14 10:21:19 server listening at [::]:50051
# クライアント $ go run greeter_client/main.go 2023/01/14 10:16:14 Greeting: Hello world
# リクエスト受信時のサーバーの出力 2023/01/14 10:21:41 Received: world
メソッドを追加して、リクエストとレスポンスの型もそれぞれ定義する。
~Replyってなんか違和感がある。
// [...] service Greeter { // Sends a greeting rpc SayHello (HelloRequest) returns (HelloReply) {} rpc SayHey (HeyRequest) returns (HeyReply) {} } // [...] message HeyRequest { string name = 1; } message HeyReply { string message = 1; }
.proto
ファイルを再度コンパイルする。
先ほどインストールしたプラグインを使う。
$ protoc --go_out=. --go_opt=paths=source_relative \ --go-grpc_out=. --go-grpc_opt=paths=source_relative \ helloworld/helloworld.proto
ファイルが小さいからっていうのもあると思うけど、コンパイルめっちゃ速かった。
サーバー、クライアントそれぞれの実装をする。
// [...] func (s *server) SayHey(ctx context.Context, in *pb.HeyRequest) (*pb.HeyReply, error) { log.Printf("Received: %v", in.GetName()) return &pb.HeyReply{Message: "Hey " + in.GetName()}, nil } // [...]
// [...] ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() r, err := c.SayHey(ctx, &pb.HeyRequest{Name: *name}) if err != nil { log.Fatalf("could not greet: %v", err) } log.Printf("Greeting: %s", r.GetMessage()) // [...]
再度サーバーを立ち上げてリクエストを送信する。
レスポンスの結果が変わっていれば想定通り。
$ go run greeter_client/main.go 2023/01/14 10:43:40 Greeting: Hey world
正しい結果となった。
まとめ
チュートリアルに沿って触ってただけでは正直まだなんとも言えない感じではある。メリット、デメリット踏まえてサービスに取り入れていきたい。
業務で今すぐ必要な感じでもないので、歴史や背景も学び中がらゆっくり身につけていきたい所存。