職場でも徐々にgRPC派閥が勢力を伸ばし導入と本番運用を開始、私も逃げきれずとうとう学習してしまった。
gRPCとは?の部分は一旦流し読みでうやむやで理解しつつ、Quick Startをクリアすることで1日で仕事で導入、実装できるところまで理解を深められた。導入の抵抗感は思いのほか全くなく、めっちゃ便利という感触を得られました。(一部手間がかかる修正もあり)
以下は備忘録(ほぼチュートリアルに書いてあることそのまま)と所感。
gRPCとは?
gRPCとは何か?gRPCのトップページにこんなことが書かれている。
- Simple service definition
バイナリシリアル化ツールセットと言語であるProtocol Buffersを使用してサービスを定義
- Works across languages and platforms
様々な言語とプラットフォーム間でサービス用のクライアントとサーバースタブを自動的に生成
- Start quickly and scale
1行でランタイム環境と開発環境をインストールし、フレームワークを使用して毎秒数百万のRPCに拡張する
- Bi-directional streaming and integrated auth
HTTP/2ベースのトランスポートによる双方向ストリーミングと完全に統合されたプラグイン可能な認証
これらを理解するためにはProtocol BuffersとRPCという用語も知っておく必要がある 。
- Protocol Buffersはインタフェース定義言語 (IDL) で構造を定義する通信や永続化での利用を目的としたシリアライズフォーマット。
- RPC(remote procedure call)とは、プログラムから別のアドレス空間(通常、共有ネットワーク上の別のコンピュータ上)にあるサブルーチンや手続きを実行することを可能にする技術。
要約すると、gRPCとは、Protocol Buffersを使用してデータをシリアライズ化しRPCを実現するプロトコルである。ちなみにGoogleによって開発されている。
Quick Start
gRPCとは?を流し読みした程度で、Quick Startをやると良い。すぐに理解が進む。 言語間で使えるため様々な言語のガイドがあるが、今回はGoを選ぶ。
ガイドに沿ってセットアップした後、helloworldを見てみる。
$ cd $GOPATH/src/google.golang.org/grpc/examples/helloworld
helloworld配下に.protoファイルと.pb.goファイルがある。
データ構造およびサービスはプロトコル定義ファイル(.protoファイル)でデザインされ、protocでコンパイルされる。
コンパイルによってサービス用のクライアントとサーバースタブのコード(.pb.go)が生成される。これは言語によって.pb.ccや.pb.hといったファイルにもなりうる。
gRPCの動作確認
まずはローカル環境下でサーバーを起動。
$ go run greeter_server/main.go
ターミナルで別タブを開いて、クライアントを起動。
$ go run greeter_client/main.go
Greeting: Hello world
というレスポンスを取得できるのがわかる。
gRPCのサービスを更新する
.protoファイルにはGreeterというサービスと、サービスにSayHelloというRPCメソッドが定義されている。 SayHelloはHelloRequestを受け取ってHelloReplyを返す。
// 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;
}
GreeterサービスにSayHelloAgainというRPCメソッドを追加する。
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
// Sends another greeting
rpc SayHelloAgain (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;
}
そのあと、protocでコンパイル。更新された.pb.goが生成される。
$ protoc -I helloworld/ helloworld/helloworld.proto --go_out=plugins=grpc:helloworld
gRPCの通信実装の流れ
①プロトコル定義ファイル(.protoファイル)を作成。
②protocでコンパイル。サービス用のクライアントとサーバースタブのコード(.pb.go)が生成される。
③サーバー側のRPCメソッド内の処理を記述。
④クライアントを初期化、実装(今回のスタートガイドの場合、.pb.goにNewGreeterClientがあるのでそれ使う)。
一応、肝となるのはpbファイルはサーバー側とクライアント側双方に持たせる必要があるということ。
gRPC導入のメリット
- .protoファイルにAPI仕様を書けるので、ドキュメントとして使用できる
- .protoファイルから様々な言語に応じたコードを自動生成できる、例えば、それぞれ異なる言語・プラットフォーム(例えば、Android/Java, iOS/Swift)に向けたコード生成が簡単
- パラメーターへの型付け
- サーバースタブの自動生成によってテストコードが書きやすい
gRPC導入できつかったこと
- パラメーターの型付けが厳格。例えばintでは、int64かint32のようにビット指定が必要。Goのように型に厳しい言語に途中から導入する場合、これまで変数で用いていたintをint64に修正する必要があって、修正量がかなり多くて大変だった。
- データがシリアライズされて通信されているためcurl叩けない、デバッグするためにはクライアントを自力で書く必要がある(まだちゃんと調査してないのでもっといい方法あるかも)