Now in REALITY Tech #35 通信速度改善のためのprotobuf対応
どうも、サーバエンジニアのうすぎぬです。今回は通信速度改善のためのprotobuf対応についてつらつら書いて行きます。
内容としては↓の4番で紹介されている内容の結果報告になります!
同じくの品質改善プロジェクトである配信Serverのマルチリージョン化の記事もよければ読んでね
実施内容
今回のプロジェクトはWeb APIによるデータのやりとりのデータフォーマットにおいてprotobufを利用するための環境整備だったり、開発ガイドライン整備あたりが目的になります。
整備の対象範囲は iOS, Android, Unity <-> Server あたりとしました。また、REALITYのクライアントアプリでは Native <-> Unity でデータの受け渡しを行なっており、今回はここのデータフォーマットも protobuf に置き換える対応を入れます。
protobuf とは
protocol buffers (protobuf) は、構造化されたデータをシリアライズするための言語、またはプラットフォームに依存しないシリアライズフォーマットです。データのやり取りのために使うJSONをprotobufに置き換える、というような位置付けですね。
特長として以下が挙げられます。
JSON と比較しデータが軽量で高速なシリアライゼーションを実現する
idによるfield定義が行われ、field名の変更などはある程度柔軟に行える
インタフェースは共通のproto定義を参照するためマルチプラットフォーム間のインターフェース共有が効率化される
REALITYでは現在APIのデータフォーマットにJSONを採用しており、これがprotobufに置き換わると、
Server / Clientでの負荷軽減
リリース柔軟性向上
通信データ容量削減
サービス提供者視点ではServer費用削減
ユーザ視点ではギガが減りづらくなる
などの恩恵があります。みんなハッピー!
ちなみに、protobufのシリアライズ / デシリアライズのパフォーマンスについては↓の記事でJSONとの比較があり、非常に分かりやすかったです。
環境
マルチプラットフォームでprotocのバージョンによるbuild差分が出ないように環境を整える必要があります。
今回は各platformで以下の環境に整備しました。
Server (Golang): protoc v3.17.3
Unity (C#): protoc v3.17.3
iOS (Swift): swift-protobuf
Android (Kotlin): protobuf-javalite
特にUnityではprotobufを利用するのが今回初めてと言うわけではなく、配信中のモーションデータのやり取りなどにprotobufを利用しています。以前は protoc 3.10.0 を使用しており、Unityのみoptional構文が使えない問題が発生し、ここでprotocのバージョン上げ対応を行いました(※proto3でoptionalが利用可能になったのはv3.12から)。
CI/CD
各環境を整える以外にもprotoc-gen-docによるAPI仕様書のドキュメンテーション自動化なども行っています。proto定義が更新されるたびに自動でprotoc-gen-docが走り、API仕様書が更新される仕組みです。
また、GitHub上で更新されたproto定義が各プラットフォームの環境で問題なくbuild可能かチェックするテストを導入しました。今後はproto定義に変更があったタイミングで各プラットフォームのリポジトリにPRを自動生成するところまで考えています。
開発フロー
余談に近いのですが、この章ではBackends For Frontends(BFF)の話を書きます。
REALITYのServerはマイクロサービス構成になっていますが、実施内容章のAPI環境の図の通り、Gateway Appが設置されクライアントがコールするAPIは全てGateway Appに集約されています。
まあ、このサーバアーキテクチャそのものがBFFと言えるのですが、今回はそこからさらに踏み込み、開発フローにもBFFの思想を取り入れることにしました。具体的には以下の点を実現すべく、API interface(proto定義)はクライアントエンジニアが定義するように開発ガイドラインを設計しました。(※ただしサーバエンジニアによる設計相談/レビューを必須とする)
レスポンス中のクライアント処理に不要なパラメータの排除
1 screen 1 api call によるAPI設計
クライアントの画面名とAPIのpathを合わせる
美しいAPI設計を目指して行きたいですね。
効果計測
今回は、REALITYのWeb APIの中でも特に総通信データ量が多い
配信ステータス取得API
ギフト一覧取得API
のprotobuf化を行いました。
下図はギフト一覧取得APIについて、JSONで扱った時とprotobufで扱った時のクライアント視点でのレスポンスペイロードのサイズ比較の図になります。図の数値を見て取れるように約60%のサイズカットを実現しました。JSONでやりとりしていた頃もgzipなど利用し容量削減には努めていたので想像以上の効果でした。
さらに、 iOS, Android, Unity, Server すべてにおいてデータのparseにかけるリソースも減っているのでみんなハッピーです。
最後に
今回のプロジェクトではマルチプラットフォームでのprotobufによるデータ交換を実現しました。
これからも、REALITYでは本プロジェクトのように積極的にパフォーマンス改善や開発フロー改善を行なっていきます。そんなREALITYでは最高のサービスを一緒に作ってくれるエンジニアを募集しています!
気になった方は是非カジュアル面談からでもどうでしょうか