GolangでgRPCを試してみた
はじめに
gRPCに関する知識があまり整理されていなかったので、gRPCとはどういった特徴を持ったものなのかを改めて調べつつ、実際に動かしてみるところまでをやってみました。
gRPCとは
gRPCはプロセス間通信技術であり、分散した異種アプリケーションをローカル関数呼び出しのように簡単に接続、呼び出し、操作、デバッグできます。
gRPCはインタフェース定義言語 (IDL) とメッセージ交換フォーマットとしてプロトコルバッファを使用します。IDLを使用してサーバ側とクライアント側の両方がコードを生成できます。
サービスとコンシューマー間のネットワーク通信はHTTP/2で行れます。
gRPCは従来のプロセス間通信技術(CORBA,RMI,SOAP,REST...)の欠点を克服できるプロセス間通信技術として設計されています。
gRPCの利点
- It’s efficient for inter-process communication (バイナリプロトコルにより効率的なプロセス間通信ができる)
gRPCはHTTP/2の上にプロトコルバッファを実装している。 - It has simple, well-defined service interfaces and schema (シンプルでよく定義されたサービスインタフェイスとスキーマを提供)
コントラクトファーストアプローチで最初にサービス・インタフェースを定義する。 - It’s strongly typed (強い型付が定義される)
アプリケーション間の通信に使用する型が明確に定義される。 - It’s polyglot (多言語に対応している)
gRPCサービス定義は言語に依存せず好きな言語を選択することができる。 - It has duplex streaming (ストリーミング通信をサポートしている)
クライアントまたはサーバーサイドのストリーミングをネイティブにサポートしている。 - It has built-in commodity features (コモディティ機能が内蔵されている)
認証、暗号化、回復力(デッドラインとタイムアウト)、メタデータ交換、圧縮、負荷分散、サービス発見などのコモディティ機能のサポートしている。 - It’s integrated with cloud native ecosystems (Cloud Nativeエコシステムと統合されている)
gRPCはCNCFの一部で最新のフレームワークのほとんどはgRPCのネイティブサポートをしている。例えばEnvoyなどは通信プロトコルとしてgRPCをサポートしている。 - It’s mature and has been widely adopted (成熟していて広く採用されている)
Google、Square、Lyft、Netflix、Docker、Cisco、CoreOSなど、多くの大手テック企業が採用している。
gRPCの欠点
- Not human-readable format
メッセージはProtobufでエンコードされるので送受信は効率的だが、バイナリ形式なので人が判読できない。 - Limited browser support
REST/HTTPプロトコルに比べるとブラウザサポートはまだ限定的。
試してみた
一通りgRPCについて整理してみたところで実際に動かしてみます。
今回試してみたソースは以下のリポジトリにあります。
protoファイルを作成する
サービスの定義を記載します。
protoファイルの書き方についてはこちらを参照してください。
サーバーとクライアントのソースを生成する
Makefileにしてみました。以下のコマンドを打つとhello.proto
ファイルを元にしてhello.pb.go
とhello_grpc.pb.go
の2つのファイルが生成されます。
$ make setup
以下のコマンドで生成したファイルの削除をします。
$ make clean
動かしてみる
Server
サーバーの起動は以下のコマンドでできます。
$ go run cmd/server/server.go --port 50051
Client
上記のサーバーを起動した状態でクライアントを動かします。
$ go run cmd/client/client.go --name Alice
すると以下のように表示されたら成功です。
Greeting: Hello Alice
終わりに
ひとまずサンプルレベルですが動かしてみることができました。
またprotoファイルのlintや破壊的な変更の検知をできるBufというツールをGithub Actionsで設定してみました。
参考ページ
その他、参考にしたページたち。
Discussion