この記事ではgRPCをとにかくわかりやすく説明します。
gRPCとは?
まず正しい定義を書きます。(最初は理解が難しいので流してください)
- gRPCはGoogleが作ったRPCです
- HTTP/2の上で動作します
- Protocol Buffersを使ってデータをシリアライズ化します
- protoファイルと呼ばれるIDL(Interface Definition Language)でAPI仕様を規定します
この記事を通じて、これらが何を示しているのかを理解していきましょう。
まずはRPCを知ろう
RPCはRemote Procedure Callと呼ばれる古くから存在する技術です。RPCを使うことでリモート(Remote)にある関数/手続き(Procedure)を呼ぶ(Call)ことができます。文脈によっては個別の規格を指す場合がありますが、この記事の中では総称として用いています。
この一連の流れをRPCといいます。(NFSもRPCをつかっています)
RPCの課題
RPCにはいくつかの問題がありました
- 性能
- ネットワーク越しに関数を呼ぶと時間がかかる
- データ型変換
- 言語ごとにサポートする型が違うため変換ができない
- 負荷分散の問題
- 当時はサーバ1台とクライアント3台。といった決まった構成を前提に動かすシステムだったため、サーバ側にクライアントの状態を保持しており大規模な分散システムには利用ができない
RPCについてはこちらの書籍にて紹介されています。
gRPCとはなんなのか?
gRPCはGoogleが開発したRPC(Google Protocol RPC)で、HTTP/2の上でデータのやりとりをするプロトコル・規約です。
私たちが普段ブラウザで動画やブログ記事を見ている時は以下の図のような通信が行われています。
HTTPリクエストの中にアクセスしたいURLが含まれており、レスポンス(返事)に取得した記事(HTML)が含まれています。これをブラウザが解釈して記事が表示されています。
gRPCの場合はHTTP/2と呼ばれる進化したHTTPプロトコルを利用して通信を行います。やっていることは先ほどとほとんど同じに見えますね。違うのはHTTPを使ってリモートの関数を呼んでいるところですかね。
まずこの2つがわかりましたね。
- gRPCはGoogleが作ったRPCです
- HTTP/2の上で動作します
- Protocol Buffersを使ってデータをシリアライズ化します
- protoファイルと呼ばれるIDL(Interface Definition Language)でAPI仕様を規定します
シリアライズ化とProtocolBuffersとは?
急によくわからない単語がでてきました。大丈夫です、きちんと説明します。
シリアライズ化とは
ここでいうシリアライズ化とは「オブジェクトをバイナリデータに変換する処理」のことです。またよくわからない表現が出てきましたね。
こんな変数を作ったとします。
{ 'age': 30, 'name': 'taro' }
この変数は name = taro
と age = 30
が設定されたオブジェクト(なんらかのモノのこと)です。これをシリアライズ化するとこんな風になります。(シリアライズ化するツールやライブラリによって結果は変わります)
(dp0 S'age' p1 I30 sS'name' p2 S'taro' p3 s.
今回の変数は非常にシンプルなため本当はシリアライズ化が不要なのですが、オブジェクトの中にはメモリのアドレスを保有していたりオブジェクトIDなどそのまま文字列化しても意味がない場合があります。その際は、変数をそのまま出力するのではなくバイナリ化するシリアライズ化が必要となります。
一体なぜシリアライズ化が必要なのか?
シリアライズ化することで本来そのアプリでしか使用できないオブジェクトを他に渡すことができるようになるからです。ちなみに、シリアライズ化されたデータを元に戻すことをデシリアライズ化と呼びます。
またシリアライズ化することによってデータ量が削減されます。
gRPCでのシリアライズ化
gRPCではクライアントとサーバ間でやりとりするデータを「シリアライズ化」しています。そしてそのときに使っているシリアライズ化の手法が「Protocol Buffers」です。
ここまできました。あともう少しです。
- gRPCはGoogleが作ったRPCです
- HTTP/2の上で動作します
- Protocol Buffersを使ってデータをシリアライズ化します
- protoファイルと呼ばれるIDL(Interface Definition Language)でAPI仕様を規定します
実際に試してみよう
続いてはgRPCについて実際にやってみて理解を進めましょう。このハンズオンの中でprotoファイルの説明が行われます。
protoファイルとはサーバで公開する関数の仕様を規定するファイルです。このファイルを使ってクライアント・サーバがgRPCを行うためのコードを生成することができます。
1種類のprotoファイルから様々な言語のコードを生成することができるため、protoファイルのみを作成することで多言語なアプリ間でのRPC通信を実施することができるようになります。
- gRPCはGoogleが作ったRPCです
- HTTP/2の上で動作します
- Protocol Buffersを使ってデータをシリアライズ化します
- protoファイルと呼ばれるIDL(Interface Definition Language)でAPI仕様を規定します
gRPCの通信の流れ
上記のハンズオンの中でsayHello
関数をgRPCで呼び出した時の動きを図解化します。
まずはクライアント側で呼び出しが行われます。この時proto
ファイルによって生成されたhelloworld_pb2.py
・helloworld_pb2_grpc.py
のコードによってgRPCに変換されHTTP/2でコネクションが張られます。
サーバ側では受け取ったgRPCメッセージをデシリアライズ化しserver.py
に渡します。
返却も同様にシリアライズ化され行われます。
まとめ
今回紹介しきれていませんがgRPCを使った時のメリットは以下の通りです
- HTTP/2やProtocol Buffersを使うことによるパフォーマンスが向上する
- 開発者はAPiをコールする処理を書くときやAPIを用意するときに
protoファイル
のみを意識すればよいので非常に楽になる(HTTP/2の恩恵も預かれる) - シチュエーションに応じた複数の言語を採用しやすくなる(各言語で作ったアプリ間の通信をgRPCに統一すればよいので)
- gRPCの仕様が厳格に規定されているためブレにくい
すでにGoogle社では社内で全般的に利用されているとのことですし、Web系の企業では利用が進んでいるということなのでこれからはやっていきそうですね。