gRPC の評価 : 複数言語のサポート具合をチェックする
Google Cloud Japan Team
gRPC は、Google が開発し、オープンソース化した RPC フレームワークです。HTTP/2 との効率的な接続、Protobuf による効率的なデータ シリアライズ、双方向ストリーミングなど、gRPC には多くの長所がありますが、なかでも特に大きな長所がとかく見落とされがちです。それは、複数のプログラミング言語をサポートしていることです。
gRPC は、そのままの形でいくつかのプログラミング言語をサポートしています。C#、Java、Go、Node.js、Python、PHP、Ruby などです。マイクロサービスの世界ではお気に入りの言語やフレームワークでサービスを実装できる柔軟性が必要とされますが、gRPC を使えばそれが手に入ります。低水準のマイクロサービス間の接続やデータ転送についても、gRPC が効率良く一貫性のある形で処理してくれます。
もっとも、これらは理屈の上ではどれも素晴らしい話ですが、本当にうまくいくのでしょうか。私は古くからの Java と C# の開発者として、複数のプログラミング言語のサポートという約束を gRPC がどれだけ果たしているか、試したいと考えました。
その方法は次のとおりです。まず、Java による gRPC のサンプルを実行することで gRPC の Java サポートをチェックします。次に、これらのサンプルがどれだけ簡単に C# に移植できるかを調べます。そして最後に、Java と C# のクライアント / サーバーを組み合わせて相互運用性をテストします。
gRPC の Java サポート
まず、gRPC が個々のプログラミング言語をどの程度サポートできているかを試してみました。Java の場合、その方法はとても簡単です。Maven もしくは Gradle の依存ファイルとプラグインを追加するだけです。同僚で Java のエキスパートである Ray Tsang が gRPC のサンプルを自分の GitHub リポジトリで公開しているので、それを動かしてみるところから始めました。私が試したのは、Java で書かれたシンプルな gRPC クライアントと gRPC サーバーです。これらは “Hello-World” タイプのサンプルであり、クライアントがサーバーに要求を送信するとサーバーがエコー バックしてきます。このサンプルは Maven プロジェクトなので、お気に入りの Java エディタ(Eclipse)を使用し、プロジェクトを新しいワークスペースにインポートしました。
最初にサーバーを起動しました。
次はクライアントの起動です。クライアントは仕様どおりに要求を送り、サーバーからの応答を受信しました。
同僚の Ray は、双方向ストリーミング機能を使った面白いサンプルも作っています。チャット サーバーと、このサーバーとやり取りする JavaFX ベースのチャット クライアントです。ほんのわずかな作業で、2 つのチャット クライアントはチャット サーバー経由で互いに話し合えるようになりました。
gRPC の C# サポート
次に、同じサンプルを C# でどれくらい簡単に記述できるかを試してみました。gRPC のドキュメントにあるサンプルを参考に、Hello World サンプルの GreeterClient と GreeterServer を作りました。C# で書いたコードは Java のそれとよく似ていますが、多少良くなっているように見えます(実は私は C# のほうが好きなのです :-))。両者には小さな違いが 1 つあります。Java の場合は Maven か Gradle のプラグインを使用して gRPC スタブ クラスを自動生成できますが、C# の場合は gRPC Tools という NuGet パッケージを導入し、それでスタブ クラスを生成しなければなりません。
generate_protos.bat を見ていただくと、私がどのように対応したのかがわかります。幸い、Java と C# のスタブ クライアントの生成には同じサービス定義ファイルを使うことができます。そのおかげで、クライアントとサーバーの各アプリケーションを別の言語で記述することも簡単です。
双方向ストリーミングのチャット サンプルである ChatServer と ChatWindowsClient も作りましたが、こちらは JavaFX ではなく Windows Forms を使いました。前述の例と同様にコードは Java 版とよく似ていますが、gRPC は言語の特徴を生かし、開発者が言語固有の機能を見逃さないようにしてくれます。
たとえば、ChatServerImpl.java
はクライアント メッセージのハンドラとして StreamObserver
を生成して返します。これはこれで機能しますが、少々わかりにくい感じがします。それに対して ChatServerImpl.cs
は、C# の async / await パターンを使って応答ストリームを非同期に出力します。こちらのほうがクリーンな実装になります。
gRPC の複数言語テスト
複数のプログラミング言語のサポート具合を見極めるうえで必要な本当のテストは、Java と C# の実装がどれだけうまく相互運用できるかです。このテストのために、まず Java のチャット サーバーを起動し、このサーバーとやり取りする Java クライアントと C# クライアントを起動しました。すると、特別な構成や準備を必要とせずに、2 つのクライアントはサーバーを介して通信することができたのです。
まとめ
フレームワークの設計はただでさえ難しいものですが、個々のプログラミング言語の特徴を生かしながら言語の違いを超えて動作するフレームワークを設計するとなると、さらに難しくなります。今回のテストでは、gRPC を Java でも C# でも違和感なく使用できました。それぞれの言語の特徴を生かした形で gRPC をサポートするために、十分に検討を行い、多くの労力を注ぎ込んでいることは明らかです。広範な言語をこのレベルでサポートしていることは素晴らしいと思います。
ここで紹介したサンプルを実行してみたい方は、Ray の Java gRPC サンプルと私の C# gRPC サンプルをご覧ください。彼が Java gRPC をテーマに講演したときの動画もあります。
* この投稿は米国時間 5 月 8 日、Developer Advocate である Mete Atamel によって投稿されたもの(投稿はこちら)の抄訳です。
- By Mete Atamel, Developer Advocate