Voicy史上最大のバックエンド改修! ~BFFとKubernetesでVoice Techの荒波を乗り越えろ~
こんにちは!!
VoicyでWebアプリケーション開発を担当しているぱんでぃーです!!
今回は “まさに今” 進行中の大型プロジェクトについて紹介したいと思います。
TL;DR
- 事業領域の拡大により、似たようなドメインロジックが各バックエンドに点在してしまっている。
- システム改修コストを抑え、機能差分を無くすために、ドメインロジックをまとめる共通APIを開発したい!!
- そして、各プロダクトごとにBFFを構築し、固有のロジックや認証・認可を担当させると幸せ度が上がるのでは!?
Why We Resolve? ~Problem of Current System~
まずは現行のバックエンドの課題について、簡単にご説明します。
通常であれば、スタートアップ企業は1つのプロダクトに特化し、クライアントアプリ、バックエンドのAPIサーバーは1つづつというケースが多いのではないでしょうか?(開発リソースがあればクライアントアプリはiOS、Android、Webに展開、といった感じでしょうか)
一方で、Voicyはクライアントアプリだけでも下記の4つが存在します。
- リスナー向けVoicyアプリ(以下、Voicy Player)
- パーソナリティ向けVoicyアプリ(以下、Voicy Recorder)
- クライアント企業向けの管理画面
- 社内メンバー向けの管理画面
さらに、Voicy PlayerについてはiOS、Android、Webアプリを提供しているのですが、図解すると以下のような構成になっています。(実際には、スマートスピーカー用のエンドポイントや音声処理用のマイクロサービスなど、他のプロダクトもありますがここでは問題を強調するために簡略化してあります)
お気づきの方も多いと思いますが、似たようなドメインロジックが各APIサーバーに点在してしまっています。もちろんクライアントアプリ側の画面構成や(とくに管理画面系の)認証・認可のロジックは大きく異なるのですが、扱っているリソースデータは共通しているものが多いです。
また、一部はJava、残りはGoで書かれていたり、RESTfulなインターフェイスになっていないものがあったりと、一貫性の無いシステム設計になってしまっています。
これには下記のような問題があります。
- 機能追加やドメインロジックの変更時に改修コストが倍増してしまう。
- ミドルウェア(DBスキーマなど)に対する変更リスクが大きい。
- インターフェイスや言語が統一されていないことによる、学習コストやコンテキストスイッチの増大。
現在、Voicyではメディアとしてのアプリケーション開発だけでなく、音声配信プラットフォームとしての開発も進めています。
価値を生まないところにリソースを投下している余裕は1ミリも無いため、このような問題を解決することは急務となっています。
このような構成となっている理由は、『サービス立ち上げ時の開発リソース』や『必要になった経緯』など、様々な要因が絡んでいるため、一概には言えませんが、意外と似たような課題を抱えている開発組織も多いのではないでしょうか?
What We Want? ~Requirements for Voice Platform~
それでは、どのような要件を満たしているアーキテクチャであれば良いのでしょうか?どうすれば今後、Voicyが音声プラットフォームとして急成長するための基盤となりうるのでしょうか?
大きなポイントとしてはこの3つです。
- 共通のドメインロジックは1箇所に集約させる。
- 様々なプロダクトごとに扱いやすいインターフェイスを提供する。
- アプリケーションに固有のロジックや認証・認可といったアクセス管理は疎結合にし、柔軟に変更できるようにする。
これらはマイクロサービスの文脈でも語られることが多いです。となると、現状のアプリケーションで提供している機能を切り分けて、マイクロサービスとして設計する・・・と考えても良さそうですね。
しかし、Voicyで扱うドメインは現状ではそれほど複雑ではなく、エンジニア組織としての規模もまだまだ小さいです。(執筆時点ではエンジニアは5人・・・!!)そのため、マイクロサービス化によるメリットよりも、複雑性を持ち込んでしまうデメリットの方が大きいと判断しました。
How We Can? ~Technical Resolution~
そして、最終的に下記のようなアーキテクチャでバックエンドを再設計するとこになりました。
ポイントとしては以下です。
- MySQLやElasticsearchなどのミドルウェアと直接やり取りを行うのはモノリシックな共通APIのみ。
- クライアントから扱いやすいインターフェイスと固有ロジックを提供するためBFF(Backends For Frontends)を構築。
- 開発スピードを最大化するためにDockerとCI/CD環境は必須。
- コンテナオーケストレーションツールとしては、既に社内で利用実績のあるKubernetes。学習コストは高いが、サーバーリソースやネットワークを柔軟に管理でき、将来的にマイクロサービス化することも見越しての採用。
- バックエンドはすべてGoに統一し、エンジニアのスキル向上スピードやノウハウの蓄積を最大化させる。
BFFについては下記の連載記事が詳しいため、まだ馴染みの薄い方は一読をオススメします。
また、絶賛検討中のこともあります。
Kubernetesについては既に社内用管理画面のバックエンドとしてGKE(Google Kubernetes Engine)を使っていますが、昨年の12月にAmazon EKS(Elastic Container Service for Kubernetes)の東京リージョンが発表されたため、このタイミングでKubernetesマネージドサービスの選定を行う予定です。
現状では、Kubernetesのマネージドサービス単体で見ればGKE一択なのですが、Voicyの既存システムの多くはAWSで稼働しているため、総合的な技術判断が必要です。
また、APIのスキーマ定義は書きやすさやメンテナンス性の高さ、拡張性の高さに優れるProtocol Buffersを採用予定です。そのためBFFとMonolithic APIとの通信についてはRESTではなく、gRPCを使うことも検討しています。昨年の10月にgRPC-WebがGAとなり、WebブラウザのJavaScriptからも直接呼び出し可能になったことで、個人的には今後利用が進んでいくと期待しています。
このへんの技術選定については今後のエントリーで紹介していく予定ですので、是非ご期待ください!!
Who Will Develop? ~It’s you!!~
さぁ、それではいったい誰が実装するのでしょうか?
それは、今このエントリーを読んでいる
あなた です!!
というのは半分冗談ですが、半分本当です!!笑
ここまでご紹介してきたバックエンドの大改修プロジェクトは、まさに今走り出したばかりです。GoやKubernetesを使い、未来の音声プラットフォームを自分の手で創り上げたい人は今すぐWanted!!
お後がよろしいようでm(_ _)m