
はじめに
オンラインサロン開発部 開発グループ アーキテクトチームの塚原です。
DMMオンラインサロンでは現行のシステムにおける課題を解決し、ビジネス的な課題を抽出しつつリプレース・リアーキテクトを進める「neon」プロジェクトに中期的に取り組んでいます。
今回は私達DMMオンラインサロンが注力している「neon」プロジェクトで利用している技術スタックについて紹介します。
neonプロジェクトについての紹介
現行のDMMオンラインサロンプロダクトのバックエンドは、PHPで作られているモノリスアーキテクチャのアプリケーションが3つ存在しています。
これらが密結合し分散モノリスのような状態になっていて、変更容易性がなく障害の発生しやすいシステムがリードタイムを徐々に悪化させるようになってしまっていました。
これらのシステム課題を解決し、価値の高いプロダクトを提供するために、サロンオーナーに提供している「オーナー管理画面」と、そのバックエンドアプリケーションのリプレース・リアーキテクトを行っています。
これらのうち、マイクロサービス+モジュラモノリスアーキテクチャを採用して作成されたバックエンドアプリケーションを「neon」と呼んでいて、neonの開発を行なっているプロジェクトを「neon」プロジェクトと呼称しています。
neonではマイクロサービス+モジュラモノリスのアーキテクチャスタイルを採用することで前述したシステム課題を解決し、ビジネスのスケールに耐え、類似サービスや機能の台頭など周辺環境の変化への迅速な対応ができるプロダクト基盤を目的として刷新を行っています。
詳しくは、以前チームリーダーの赤石が投稿した記事をご覧ください。
本記事では、neon周辺で利用している技術スタックとその採用理由について紹介します。
アプリケーション
言語: Go
IPC: gRPC
IDL: Protocol Buffers
Go
neonのマイクロサービス・モジュラモノリスのアプリケーションではすべてGoを採用しています。
Goの採用理由としては、全社的な技術戦略に加え、学習コストに対するパフォーマンスの高さや後方互換性の高さなどが挙げられます。
現行のオンラインサロンプロダクトのバックエンドはほぼすべてPHPで開発されており、PHPからGoへ移行となりましたが、Goのシンプルな言語仕様のおかげでGo未経験の開発メンバーも問題なくキャッチアップして開発できています。
gRPC
マイクロサービス・モジュラモノリス間の通信プロトコルにはgRPC、シリアライズフォーマットにはProtocol Buffersを採用しています。
基本的にクライアントコードを生成して利用することになるので、型システムの恩恵を享受でき、パフォーマンスの高い通信が可能になります。
また、Protocol Buffersは protoc-gen-docというドキュメント生成プラグインやBuf Schema Registry等を利用することで、簡単にドキュメント化することができます。
neonでは、protoc-gen-docと Facebookが開発しているOSSのドキュメントフレームワークである「Docusaurus」を利用してドキュメントを生成し、GitHubPagesでホスティングしています。
当初はBuf Schema Registryを利用していましたが、2023年に料金形態の変更がありTypeベースの課金形態に変更されました。
利用継続する場合、当時利用していたType数で月額5万円ほどの金額になり、利用ケースに見合ったコスト感ではないと判断したため自前でホスティングしています。
モノレポ
マイクロサービス・モジュラモノリスのコードはモノレポで管理していて、構成は以下のようになっています。
モノレポを採用している理由には、一般的にもメリットとして挙げられる以下のような点があります。
- チーム規模的にサービスperチームのような構成にできないためモノレポの方がチームに合っていて開発効率が高くなると判断した
- コードベースを共通利用しやすい
- 依存パッケージのバージョン管理が容易
しかしモノレポで開発を行なっている上で、以下のようなデメリットも見えてきました。
- 差分がある箇所のみCIを実行する等の仕組みを導入しないとCIにかかる時間が長くなってしまう
- これはチーム内でも問題になっていて、改善を検討中です
- 同じ名前のパッケージ名が複数存在するため、importの補完がつらい時がある
- goでは、internalパッケージを取り入れることで不要な参照を避けることができます
インフラ
neonのインフラには主にAWSを採用しています。
現行プロダクトもAWS上で動作していることや、既存リソースとの通信性やリソース管理の観点を考慮し、AWSを採用しています。
ECS Fargate
マイクロサービス・モジュラモノリスのアプリケーションはECS Fargate上で動作していて、サービスメッシュとしてAppMeshを採用しています。
EKSも検討しましたが現状のチーム構成だと管理コストを割くのが難しいと判断したため、現行プロダクトでも採用していて知見があるECS Fargate+AppMeshを採用しました。
データストア
データストアとしては Aurora MySQLを採用しています。
Cloud Spannerや TiDBといったNewSQLも導入を検討していましたが、Aurora MySQLと比較した際に、当時のコスト感で数倍違ったことから現チームでの導入は難しいという結論になり、導入を見送りAurora MySQLを採用することにしました。
分散トランザクション管理
マイクロサービス・モジュラモノリス間の分散トランザクション管理として Temporal Cloudを採用しています。
Temporalは Uberが開発している Cadenceをフォークして開発されているOSSで、Cadenceの元開発者が開発を行なっています。
分散トランザクション管理ツールの他の候補としては
- AWS Step Functions
- Cadence
- Temporal
- Cloud
- セルフホスト
- DTM
等がありましたが、ワークフローをコード管理ができる点やから Temporal を採用しています。
また、TemporalはセルフホストではなくCloud版を利用しているのですが、AWS上にセルフホストする前提でコストを比較したところ、Temporal Cloudの方がかなり安価に利用することができ、かつTemporal社のテクニカルサポートを受けることができるため、Cloud版を利用しています。
Temporal に関しての詳細は割愛しますが、後日、別の記事として公開する予定です。
認可基盤
マイクロサービス・モジュラモノリス間の認可には、Googleが開発しているZanzibarと呼ばれる、関係性ベースのアクセスコントロールを行う認可基盤にインスパイアされて開発されたOSSである、SpiceDBを採用しています。
DMMオンラインサロンでは、
- サロンごとに投稿できる/できない、 コメントできる/できない等の権限設定ができる
- 管理権限も存在している
- 将来的にDiscordのような柔軟な権限設定ができるようにしたい
という要件があり、柔軟な権限設定ができるようにRelationship-based access control (ReBAC)ベースの認可システムを採用しています。
SpiceDBをつかうと、細かい認可の制御が高いパフォーマンスで容易に利用できます。
definition user {}
definition team {
relation member: user
}
definition resource {
relation reader: user | team#member
permission view = reader
}
※ 公式ドキュメントから抜粋
このような形式のスキーマでリソースとユーザの関係性を定義し
resource:hoge#view@user:fuga
リソース(resource:hoge)に対して、指定したユーザ(user:fuga)に権限(view権限)があるかをチェックすることができます。
詳細は割愛しますが、SpiceDBではPlaygroundも提供されているので気になった方は触ってみてください。
同様のサービスで要件を満たすものは他にもいくつかあり、Auth0 FGA やその他OSSも検討しましたが、検討当時はAuth0 FGAはGAされておらず、他のOSSもStable VersionではなかったためSpiceDBを採用しました。
SpiceDBはLSPの追加(https://github.com/authzed/spicedb/pull/1854)等もあり、今後にも期待できるサービスです。
終わりに
今回はneonプロジェクトの技術スタックについてご紹介させていただきました。
DMMオンラインサロンでは開発グループのメンバーを募集しています。
比較的モダンの技術スタックを用いてのリプレースが気になるに方は、ぜひ今回の記事では語りきれなかったことをご紹介したいと思っているので、気軽に話を聞きに来てください。