Google Cloud Platform

gRPC の評価 : 複数言語のサポート具合をチェックする

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)を使用し、プロジェクトを新しいワークスペースにインポートしました。

最初にサーバーを起動しました。

  Starting server on port 8080
Server started!

次はクライアントの起動です。クライアントは仕様どおりに要求を送り、サーバーからの応答を受信しました。

  Sending request
Received response: Hello there, Mete

同僚の Ray は、双方向ストリーミング機能を使った面白いサンプルも作っています。チャット サーバーと、このサーバーとやり取りする JavaFX ベースのチャット クライアントです。ほんのわずかな作業で、2 つのチャット クライアントはチャット サーバー経由で互いに話し合えるようになりました。

6J_2r1waFICoeOLoyy-cHfykX__3t3Byv1gCg3Pc5YGhcWkqP0r-ynFRFaZS4dqgFysOVbO28qhRuuHUCwp1IN2hWnf2EnGkh7ucxHTDRzJ4dsBe4kcMoRRxuYw-LttnoUi7zBlig6ku.PNG
Java サーバーを介して通信する 2 つの JavaFX クライアント

gRPC の C# サポート

次に、同じサンプルを C# でどれくらい簡単に記述できるかを試してみました。gRPC のドキュメントにあるサンプルを参考に、Hello World サンプルの GreeterClientGreeterServer を作りました。C# で書いたコードは Java のそれとよく似ていますが、多少良くなっているように見えます(実は私は C# のほうが好きなのです :-))。

両者には小さな違いが 1 つあります。Java の場合は Maven か Gradle のプラグインを使用して gRPC スタブ クラスを自動生成できますが、C# の場合は gRPC Tools という NuGet パッケージを導入し、それでスタブ クラスを生成しなければなりません。

generate_protos.bat を見ていただくと、私がどのように対応したのかがわかります。幸い、Java と C# のスタブ クライアントの生成には同じサービス定義ファイルを使うことができます。そのおかげで、クライアントとサーバーの各アプリケーションを別の言語で記述することも簡単です。

双方向ストリーミングのチャット サンプルである ChatServerChatWindowsClient も作りましたが、こちらは JavaFX ではなく Windows Forms を使いました。前述の例と同様にコードは Java 版とよく似ていますが、gRPC は言語の特徴を生かし、開発者が言語固有の機能を見逃さないようにしてくれます。

たとえば、ChatServerImpl.java はクライアント メッセージのハンドラとして StreamObserver を生成して返します。これはこれで機能しますが、少々わかりにくい感じがします。それに対して ChatServerImpl.cs は、C# の async / await パターンを使って応答ストリームを非同期に出力します。こちらのほうがクリーンな実装になります。

gRPC の複数言語テスト

複数のプログラミング言語のサポート具合を見極めるうえで必要な本当のテストは、Java と C# の実装がどれだけうまく相互運用できるかです。

このテストのために、まず Java のチャット サーバーを起動し、このサーバーとやり取りする Java クライアントと C# クライアントを起動しました。すると、特別な構成や準備を必要とせずに、2 つのクライアントはサーバーを介して通信することができたのです。

MyfU-v9nknqwrRZ2ibuatQ8ZSrstCAnUGO-yU3OuySsti-v77a-FqX9hmcEDto0QJ21kLX9_-nY9v0I2dJs4kw9aUlHmFQReEesiWrSPymITVepYh8Va6W_QQPYvHJsrjRrNiNIjkmfd.PNG
Java サーバーを介して通信する Windows Forms クライアントと JavaFX クライアント

まとめ

フレームワークの設計はただでさえ難しいものですが、個々のプログラミング言語の特徴を生かしながら言語の違いを超えて動作するフレームワークを設計するとなると、さらに難しくなります。

今回のテストでは、gRPC を Java でも C# でも違和感なく使用できました。それぞれの言語の特徴を生かした形で gRPC をサポートするために、十分に検討を行い、多くの労力を注ぎ込んでいることは明らかです。広範な言語をこのレベルでサポートしていることは素晴らしいと思います。

ここで紹介したサンプルを実行してみたい方は、Ray の Java gRPC サンプルと私の C# gRPC サンプルをご覧ください。彼が Java gRPC をテーマに講演したときの動画もあります。

* この投稿は米国時間 5 月 8 日、Developer Advocate である Mete Atamel によって投稿されたもの(投稿はこちら)の抄訳です。

- By Mete Atamel, Developer Advocate