ITエンジニアの本棚

ITエンジニアに有益な書籍や勉強法について紹介していくサイトです。

grpc-goをDockerで手軽に試してみた

スポンサード リンク

Microservices - Wikipediaなる考え方が広まった影響なのか、数年前から各サービスを疎結合にして、APIで連携させるという開発が多い。 私が担当する開発はRESTを利用することが多かったのだが、バックエンド間の通信ではgRPCも話題に挙がることが多くなってきたため、今回試してみることにした。

gRPCとprotocol buffers

grpc / Overviewによると gRPCは、protocol buffersをIDLかつ通信用メッセージフォーマットとして利用することができるらしい。 IDLを記述しておけば、C++, Java, Python, Goといった任意の言語のserver/clientスタブを生成することができる。 今回は、Goを試すことにした。

IDLで定義してスタブも生成すれば、API仕様の伝達ミスが減るので良さそうではある。またRESTのようにSwaggerとRAMLのどちらを使うべきかといった議論が起きないのは嬉しい。 RESTでは、設計する人間によって品質レベルに大きく差が出ることが多いが、このIDLはある程度は誰でも迷うことなく記述可能なのか気になるが、まだ調べていない。

環境構築

Dockerイメージがあったのでそちらを利用することにする。 以下のコマンドを実行するだけで、GoでgRPCとprotocol buffersを利用するのに必要なものが全て揃った環境に入ることができる。

$ docker run -it grpc/go
# cd /go/src/google.golang.org/grpc/examples/helloworld/

以降に出てくるコマンドは全てDockerコンテナ内の上記ディレクトリ内での操作となる。

Hello World

grpc-go/examples at master · grpc/grpc-go · GitHubを参考に試している。

まずは動かして見る

  • helloworld.protoを作成
  • helloworld.pb.goを生成
  • pb.goを利用して、cliet/serverコードを実装
  • 実行

という流れになるが、先ほど起動したDockerコンテナの中には既に全て準備されているので、まずは実行してみる。

# go run greeter_server/main.go &
# go run greeter_client/main.go
2018/01/03 01:47:02 Greeting: Hello world

とすることで、Hello Worldが返ってくることが確認できる。 以降で、Hello Worldを実行するまでに必要な処理をまとめる。

helloworld.protoの作成

自分で写経してみた方が良いが、Dockerコンテナ内にすでに含まれているので、それを貼り付けておく。

# cat helloworld/helloworld.proto 

syntax = "proto3";

package helloworld;

// 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;
}

これが、IDLで定義したものとなる。

helloworld.pb.goの生成

.proto fileを元にGo用のclient/serverスタブを生成する。こちらもDockerコンテナ内に含まれていて、

# cat helloworld/helloworld.pb.go

で見ることができる。

自分で生成するためのコマンドは、

# mkdir hello
# protoc -I helloworld/ helloworld/helloworld.proto --go_out=plugins=grpc:hello

出力先を変えているので、自分で生成したファイルと、元々あったファイルで同じものができていることを確認して見ると良い。

server/clientコードの実装

server/clientについて、それぞれ生成したhelloworld.pb.goを利用して、

# cat greeter_server/main.go 
# cat greeter_client/main.go 

に書いてあるように実装する。余裕があるならrequest/responseで送るメッセージを少し変更して見ると良い。

まとめ

試すだけなら簡単にできた。examplesディレクトリには、route_guideという別のサンプルもあるので、あとで試してみようと思う。 次は、準正常や異常系をIDLでどのように表現するかについて調べてみてわかったら備忘用の記事としてまとめる予定である。