2.

gRPCとは|仕組み・4つの通信方式・RESTとの違い

編集
この記事の要点
  • gRPCは、Googleが開発したオープンソースのRPC(リモートプロシージャコール)フレームワークで、Protocol BuffersHTTP/2を組み合わせた高性能な通信を特徴とします。
  • インターフェースを.protoファイルでスキーマ定義し、各言語向けのクライアント/サーバーコードを自動生成する流れが基本です。
  • 通信方式はUnary(1対1)/Server streaming/Client streaming/Bidirectional(双方向)の4種類があります。
  • バイナリ形式のシリアライズと多重化により、テキストベースのRESTと比べて高速・低オーバーヘッドになりやすい一方、ブラウザからの直接呼び出しには標準では非対応で、gRPC-Webなどの仕組みが必要です。
  • 主な用途はマイクロサービス間の内部通信で、人間が直接読みにくい点やスキーマ管理といった運用上の注意点もあります。

 

gRPCとは

gRPCは、Protocol BuffersとHTTP/2を使う高性能なRPC(Remote Procedure Call)フレームワークです。Googleが社内向けに開発していた仕組みをベースにオープンソース化したもので、現在はCNCF(Cloud Native Computing Foundation)のプロジェクトとして開発が続けられています。「gRPC」の名称は再帰的な頭字語(gRPC Remote Procedure Calls)として説明されることが一般的です。

RPCは「ネットワーク越しのメソッド呼び出しを、ローカル関数を呼ぶような感覚で書けるようにする」考え方です。gRPCはこのRPCの一実装で、通信に用いるデータ構造とサービスのインターフェースをスキーマ(.protoファイル)として明示的に定義し、そこから各プログラミング言語向けのコードを自動生成する点に特徴があります。これにより、異なる言語で書かれたクライアントとサーバーが、共通の取り決めに沿って効率よく通信できます。

主に分散システムやマイクロサービスアーキテクチャにおけるサービス間の内部通信で採用されることが多く、低レイテンシかつ帯域効率の高い通信が求められる場面で利用されています。なお「フレームワーク」と呼ばれますが、Webアプリのテンプレート機能やルーティングのような機能を備えたWebフレームワークとは役割が異なり、あくまで通信・RPCのための基盤である点に注意してください。

 

gRPCの仕組み

gRPCを使った開発は、おおまかに次の3ステップで進みます。

  1. Protocol Buffersでスキーマを定義する(.proto):やりとりするメッセージ(データ構造)と、呼び出せるサービスのメソッドを.protoファイルに記述します。Protocol Buffers(protobuf)は、構造化データをコンパクトなバイナリ形式で表現するためのシリアライズ機構およびIDL(インターフェース定義言語)です。
  2. コードを生成するprotocなどのコンパイラと各言語向けプラグインを使い、.protoからクライアント/サーバーの雛形コード(スタブ)を生成します。開発者は通信処理の詳細を手書きする必要が少なくなります。
  3. HTTP/2で通信する:生成されたコードを通じて、クライアントはサーバーのメソッドを呼び出します。実際のデータはバイナリにシリアライズされ、HTTP/2上でやりとりされます。

通信の土台にHTTP/2を採用していることが、gRPCの性能面の大きな要素です。HTTP/2は1つのコネクション上で複数のリクエスト・レスポンスを多重化(マルチプレキシング)でき、ヘッダー圧縮やストリーミングにも対応しています。これらの特性とバイナリシリアライズが組み合わさることで、低オーバーヘッドな通信が実現しやすくなっています。

 

4つの通信方式

gRPCでは、サービスメソッドの定義方法に応じて4種類の通信パターンを使い分けられます。ストリーミングはHTTP/2のストリーム機能を活用して実現されています。

通信方式リクエストレスポンス主な用途の例
Unary(単項)1件1件一般的な1回の要求と応答。最も基本的な形
Server streaming1件複数(ストリーム)大きなデータの分割配信、進捗・通知の継続的な配信
Client streaming複数(ストリーム)1件大量データのアップロード、計測値のまとめ送信
Bidirectional streaming(双方向)複数(ストリーム)複数(ストリーム)チャット、リアルタイムなデータ送受信

双方向ストリーミングでは、クライアントとサーバーが互いに独立してメッセージを送り合えるため、リアルタイム性が求められる用途に向いています。どの方式を使うかは.protoのメソッド定義(引数・戻り値にstreamを付けるかどうか)で決まります。

 

gRPCの主な特徴

  • 高速・低オーバーヘッドになりやすい:データをバイナリ形式でシリアライズし、HTTP/2の多重化やヘッダー圧縮を活用するため、テキストベースの通信と比べて転送量・処理コストを抑えやすい傾向があります。実際の性能は通信内容や実装条件によって変わります。
  • 多言語対応:C++、Java、Python、Go、C#、Ruby、Node.js、Kotlinなど、多くの言語向けに実装やコード生成がサポートされています。.protoを共有すれば、異なる言語で書かれたクライアントとサーバーを連携させられます。
  • 双方向ストリーミング:前述の4方式により、単純な要求応答だけでなく、継続的・双方向のデータ送受信を表現できます。
  • スキーマ駆動:インターフェースが.protoとして明文化されるため、クライアントとサーバーの取り決めが曖昧になりにくく、コード生成によって型の整合性を保ちやすくなります。
  • セキュリティ:TLSによる通信の暗号化に対応しており、認証や暗号化を組み合わせた構成が可能です。

 

RESTとの比較

WebのAPIでは長くREST(多くはHTTP/1.1上のJSON)が使われてきました。gRPCとRESTは目的が重なる部分もありますが、設計思想や得意分野が異なります。どちらが優れているという話ではなく、用途に応じた使い分けが基本です。

観点gRPCREST(一般的な構成)
データ形式Protocol Buffers(バイナリ)が標準JSONなどのテキストが一般的
通信プロトコルHTTP/2が前提HTTP/1.1でも利用可能
スキーマ定義.protoで明示的に定義しコード生成OpenAPIなどで補えるが必須ではない
ストリーミング双方向を含む4方式に標準対応標準では要求応答が基本
ブラウザからの直接利用標準では不可(gRPC-Web等が必要)容易(広く対応)
人による可読性バイナリのため直接は読みにくいテキストで読みやすい

大まかには、外部公開APIやブラウザから直接叩くAPIにはRESTが扱いやすく、内部のサービス間通信で性能やストリーミングを重視する場面ではgRPCが選ばれやすい、と整理できます。両者を併用し、外向きはREST、内部はgRPCといった構成をとることもあります。

 

主なユースケース

  • マイクロサービス間通信:gRPCが最もよく使われる領域です。多数のサービスが相互に通信する分散システムで、低レイテンシかつ型の整合した通信を実現する手段として採用されます。
  • クラウドネイティブな基盤:軽量で効率的な通信が求められるクラウド環境のコンポーネント間連携で利用されます。
  • リアルタイム通信:双方向ストリーミングを活かし、データの継続的な送受信が必要な機能の実装に用いられます。
  • モバイルアプリとバックエンドの通信:通信の効率や多言語対応の観点から、モバイルクライアントとサーバー間の通信に用いられることがあります。

一方で、ブラウザのフロントエンドから直接呼び出す用途や、広く外部に公開して多様なクライアントから利用させたいAPIでは、RESTのほうが適している場合が多くあります。

 

.protoの例とコード生成の流れ

以下は、挨拶メッセージを返すシンプルなサービスを定義した.protoファイルの例です。serviceでメソッドを、messageでやりとりするデータ構造を定義します。

syntax = "proto3";

 

package greet;

 

// サービス(呼び出せるメソッドの集まり)の定義

service Greeter {

  rpc SayHello (HelloRequest) returns (HelloReply);

}

 

// リクエストのメッセージ定義

message HelloRequest {

  string name = 1;

}

 

// レスポンスのメッセージ定義

message HelloReply {

  string message = 1;

}

メッセージ内の= 1はフィールド番号で、バイナリにエンコードする際の識別子として使われます。フィールド名そのものではなくこの番号で対応付けが行われるため、いったん公開した番号は変更しないのが原則です。

この.protoをコンパイラにかけると、指定した言語のコードが生成されます。たとえばPython向けに生成する場合は次のようなコマンドになります。

# Python向けにメッセージとサービスのコードを生成する例

python -m grpc_tools.protoc -I. \

  --python_out=. \

  --grpc_python_out=. \

  greet.proto

生成されたコードには、クライアントから呼び出すためのスタブと、サーバー側で実装すべきインターフェースが含まれます。開発者はサーバー側でメソッドの中身(上の例ではSayHelloの処理)を実装し、クライアント側では生成済みのスタブを通じてメソッドを呼び出すだけで通信できます。使用するツールやプラグイン、オプションは言語によって異なるため、実際の手順は対象言語の公式ドキュメントを確認してください。

 

落とし穴・注意点

注意点内容
ブラウザから直接呼べない標準のgRPCは、HTTP/2の低レベルな制御を必要とするため、Webブラウザから直接呼び出すことが基本的にできません。ブラウザから利用したい場合はgRPC-Webという仕組みを使い、ブラウザとサーバーの間にプロキシを置く構成が一般的です。フロントエンドのフレームワーク(React、Angular、Vueなど)と組み合わせる際は、この点を前提に設計します。
デバッグ・可読性通信内容がバイナリのため、ブラウザの開発者ツールなどでそのまま中身を読むことが難しく、JSONのような直感的な確認がしにくくなります。動作確認にはgrpcurlなどgRPC対応のツールを用いることが多く、テキストAPIに比べて準備が必要になる場面があります。
スキーマ管理.protoがクライアントとサーバー双方の取り決めになるため、複数のサービスやチームで共有・バージョン管理する運用が重要です。フィールド番号の付け替えや互換性を壊す変更を行うと、既存クライアントとの通信に影響します。互換性を意識した変更ルールの整備が求められます。

 

よくある質問(FAQ)

Q. gRPCはWebフレームワークの代わりになりますか?

A. いいえ。gRPCはサービス間の通信(RPC)を担う仕組みであり、HTMLのテンプレートやルーティングといったWebフレームワークの機能は備えていません。Webアプリでは、画面表示を担うフロントエンド側に別途WebフレームワークやSPAを用い、バックエンドのサービス間通信や一部のAPIにgRPCを使う、といった役割分担が一般的です。

Q. RESTと比べて必ず速いのですか?

A. 一概には言えません。バイナリシリアライズやHTTP/2の多重化により有利になりやすい設計ではありますが、実際の速度は通信内容、ペイロードのサイズ、実装、ネットワーク条件などに左右されます。性能が要件であれば、自分たちの環境で計測して判断することが大切です。

Q. gRPCとProtocol Buffersはどう違うのですか?

A. Protocol Buffersは、データ構造を定義しバイナリにシリアライズするための仕組み(IDLとシリアライズ機構)です。gRPCは、そのProtocol Buffersをインターフェース定義とデータ形式に利用し、HTTP/2上でRPCを実現するフレームワークです。Protocol Buffers自体はgRPCと切り離してデータのシリアライズ用途だけに使うこともできます。

編集
Post Share
子ページ
  1. Protocol Buffers
  2. 詳細説明付きクイックスタート
  3. Docker + Go言語 + gRPC で簡単なWebアプリケーションを作る その1
同階層のページ
  1. RESTサービス
  2. gRPC
  3. シングルトン
  4. コンテントタイプ(Content-Type)一覧
  5. sitemap.xml
  6. Feed
  7. ブロックチェーン

最近更新/作成されたページ