RSocketは、単一のネットワークコネクションの上で多重化されたメッセージのストリームとして通信をモデル化した,非同期ネットワーク通信プロトコルである。QCon London 2019で行ったプレゼンテーションの中で,Robert Roeser氏は,RSocketを開発した理由と,そこで使用されている通信モデルについて説明した。同じプレゼンテーションでは,Ondrej Lehecka氏が2つのユースケースを説明し,Andy Shi氏はRSocketのメリットを活用したデモを実施している。
NetifiのCEOで,以前はNetflixにいたRoeser氏の説明は,Netflix在籍時,分散システムの構築を容易にするプロトコルの開発を決意した理由から始まった。氏のチームは当時,アプリケーションが相互にネットワーク上で,一貫した方法で通信するための標準的な方法を確立したいと考えていた。これにはマイクロサービスだけでなく,関連する他のデバイスも含まれる,と氏は述べている。
分散システムの構築時にRSocketが何を提供できるのか,という疑問に対して,Roeser氏は3つのものを挙げている。
- ネットワークを介した通信モデル
- ノード間でデータを伝送する手段 — ネットワークプロトコル
- ノード間のフロー制御
RSocketの通信モデルはメッセージベースのバイナリプロトコルを採用していて,バイナリフレームをメッセージとして送信することで相互に対話する,リクエスタとレスポンダという概念を使用している。可読性のあるフォーマットではなくバイナリフォーマットを選択したのは,テストの結果,バイナリフォーマットの方が30パーセント高速であることが分かったからだ。これによって,レイテンシの低減が実現した。Roeser氏にとってこれは,サービスグラフ下のすべての呼び出しに影響することから,分散システムにおいては重要なことだ。また,ペイロードの内容は任意であるため,あらゆるユースケースをサポートすることができる。
RSocketは多重化されたコネクション指向のプロトコルである。毎回新たなリクエストを生成する必要のあるプロトコルは非常に非効率だ,とRoeser氏は指摘する。RSocketでは,各クライアントがインフラストラクチャへのコネクションをひとつ生成して,仮想ストリームを通じて複数のリクエストを送信する方法を採用している。この方法には多重化の問題が伴うが,Rsocketでは各メッセージをストリームIDで修飾して,コネクションを論理ストリームに分割可能にすることでこれを解決している。これによって,より効率的なコネクションの利用が可能になると同時に,使用するコネクション数が少なくなることから,サーバの数も少なくて済む,と氏は主張する。
ネットワークレベルに目を移すと、RSocketはさまざまなインタラクションモデルを提供している。
- リクエスト/レスポンス — ひとつのストリームとして,メッセージを送信し,ひとつのメッセージを受信する。
- ファイア・アンド・フォーゲット — ひとつのフレームを送信するが,何も戻らない。これはレスポンスを無視するという意味ではない。何も返さないということは,それよりも効率的なのだ,とRoeser氏は指摘する。
- リクエスト/ストリーム — ひとつのリクエストを送信し,レスポンスとしてストリームを受け取る。
- チャネルあるいは双方向ストリーム — リクエストのストリームを送信して,レスポンスのストリームを受信する。
RSocketのユニークな機能のひとつとしてRoeser氏が考えているのは,双方向であるという点だ。クライアントがサーバに対してコネクションを開始した後は,クライアントとサーバの間に違いはない。同等のメンバであり,どちらからも相手にデータを送信することができる。これによって,例えばWebブラウザがサーバに接続して,ブラウザ内のJavaScriptからAPIをコールすることが可能になる。RSocketにはメッセージベースのフロー制御も含まれている。これはバイト数で動作する一般的な方法とは違い,システム間を流れる1秒あたりのメッセージ数で機能するものだ。
RSocketは下位のトランスポートを抽象化しており,双方向であることをトランスポート層の唯一の要件としている。これにより,RSocket APIを使用したアプリケーションを記述すれば,ビジネスロジックを変更することなく,さまざまなトランスポートを使用することが可能になる,とRoeser氏は述べている。現在の実装では,HTTP/2,TCP,WebSocket,共有メモリがサポートされている。
Roeser氏によるRSocketの紹介に続いて,FacebookのソフトウェアエンジニアであるLehecka氏が,2つのユースケースについて説明した。ひとつめは,ライブクエリの使用に関するものだ。Facebookでは,クライアント上で定期的にアップデートする必要のあるデータを取得する手段として,GraphQLを使用している。通常ならばこれは,クライアントから定期的にクエリを実行することで実現されるのだが,RSocketを使えば,クライアントがget-and-subscribeリクエストを使用することで,更新時に自動的にライブアップデートを取得することができる。
Lehecka氏が紹介した2番目のユースケースは,クライアントの監視に関わるものだ。Facebookには多数のクライアントが接続されており,それらすべてがテレメトリやカウンタといった独自のログを収集している。これらのログはすべて、監視やクライアント側の問題のデバッグ機能などのニーズに合わせて,サーバ側に収集されなければならない。RSocketを使えば,サーバが個々のクライアントにリクエストを送信して,詳細なログのサーバへのストリーミングを起動する,という方法でこれを強化することができる。
同様のユースケースとして,AribabaのAndy Shi氏は,単一のクライアントからコンシューマに対して,データベースやバッファを使用することなく,ログファイルをストリームする方法のデモを実施した。
プレゼンテーションのスライドがダウンロード公開されている。カンファレンスの主要なプレゼンテーションは録画されており、今後数ヶ月にわたってInfoQで公開される予定である。次回のQConカンファレンスであるQCon.aiは、AIとマシンラーニングに重点を置くもので、2019年4月15~17日にサンフランシスコで開催される。QCon London 2020は、2020年3月2~6日に開催が予定されている。