📡

モノリスからマイクロサービスへ(アルダグラムの場合)

に公開

こんにちは!アルダグラムでエンジニアをしている @sukechannnn です。
アルダグラムでは企画・開発・採用とプロダクト開発に関わることを色々やってます。今回はアーキテクチャのお話です。

アルダグラムのサーバーサイドは、元々は Ruby on Rails で実装されたモノリシックな構成でした。そこから、新プロダクトの開発をきっかけにサーバーを分離して開発し始め、直近ではサービスの責務に応じてサーバーを新しく立てる方針を取っており、だんだんとマイクロサービスみが出てきました。

そこで、どんな進め方で完全なモノリスからマイクロサービス化を進めていったのかをご紹介しようと思います!

先にまとめ

  • サーバーサイドのリポジトリはモノレポで管理
  • サーバーサイドKotlinで Gradle のマルチモジュールを活用して複数サーバーを実装
    • common モジュールで認証や権限などの共通ロジックを管理しつつ、サーバーそのものの実装は完全に分離
    • サーバー毎にDBやインフラも分離し、デプロイは独立して可能に
  • サーバー間通信はいったん既存の GraphQL を流用
    • 元々あった Ruby on Rails のサーバーとも GraphQL で通信
    • 他サービスのDBを直接参照することは絶対に行わない

※プロダクトのフェーズによって最適な構成は変わるので、あくまで現状はこうという感じです。将来的に、例えば通信がボトルネックになってきたら gRPC を導入するなどを検討すると思います。

モノリスからマイクロサービスへ〜移行の流れ

元々の構成(2023年初頭)

僕が入社したのが2021年12月だったのですが、そこから1年半は以下の構成でした。

2023年3月時点のアーキテクチャ

主なバックエンドは Ruby on Rails のみでした(外部向けAPIを提供するNestJSがありますが、ロジックはほとんど書いてない)。

ただし、認証は Firebase Authentication を使っていて、チャットや通知などのリアルタイム処理は Firestore/Cloud Functions を使っています。これは後にサーバーを追加する時にとても便利でした。他サーバーから認証や通知をする時に、Rails にアクセスしなくて良いからです(先人に感謝 🙏)

新プロダクトの開発(2023年5月~)

ちょうどそのころ、新プロダクトの開発の話が立ち上がりました(後にKANNAレポートとしてリリースされます)。

この時点で、Ruby on Rails 自体がだいぶ肥大化してきており、以前から社内で「今後新しいサービスを開発する時にはマイクロサービス化しよう」と話していました(この記事で話しています)。

また、このサービスは、Excelから帳票のレイアウトを読み取ってWeb/Appで書き込み可能にしたり、記入した内容(画像含む)をExcelに書き戻したりと、Excelの操作がたくさん必要でした。色々と調査した結果、要件を満たす機能を持つライブラリがある言語(ややこしい)はJVM or C#という状況だったので、マイクロサービス化したいという流れもあり、このサービスはサーバーサイドKotlinで開発することにしました。

その時の構成が以下の通りです。

分散サーバー化(1st)

Kotlin を選んだのにはもう1つ理由があって、それが「マルチモジュール構成にできること」です。
将来的に第2第3のサービスが出てきた時に、認証やライブラリなど共通で使えるモジュールは共通で管理・利用しつつ、サービス毎にモジュールを分けて個別にサーバーを立てられるようにすることで、高速に立ち上げできるようにしたいと思ってそうしました。
実際にその後新しいサーバーを立ち上げたのですが、一瞬で立ち上げることができて良かったです。

リポジトリ構成は、既存の Rails のリポジトリの中に kotlin/ ディレクトリを切って、そこに Spring Boot のコードを入れるサーバーだけモノレポ構成にしました(元々Webフロントやアプリは別リポジトリで別れている)。これにより、1つのリポジトリをpullするだけで、最新の複数サーバーを一度に立ち上げることができます。

参考: メルカリShops の技術スタックと、その選定理由

(本当は↑記事のように ruby/ kotlin/ と言語ごとにディレクトリを切れたら綺麗なのですが、CI/CDやインフラなどあらゆるところに影響が出るので、いったん見送りました。いつかやりたいと思っています。)

2025年4月時点

直近3月にリリースした承認フローを別サーバーとして切り出して開発しました。上記の図に新しく承認フローが追加された感じです。

さらに別の機能をKotlinの別サーバーで実装中です(何を作ってるかはまだ内緒です)。

ディレクトリ構成
kanna-api
├── app
├── bin
├── config
├── db
...Rails用のディレクトリ
└── kotlin
    └── kanna
        ├── approvalflow(承認フロー)
        ├── common(共通モジュール)
        ├── config(detektなど共通の設定)
        ├── gembadocs(KANNAレポート)
        ├── newserver(新機能のサーバー)
        └── gradle

マイクロサービス化の良かったこと/課題

良いところ

KANNAプロジェクト・KANNAレポート・承認フローと横断して開発していますが、マルチモジュール内で複数サーバー&データベースを切り分けることは以下のようなメリットがあると感じています。

  • それぞれのモジュールは小さいので、
    • ビルドが速い
    • コードの把握がしやすい
  • 共通のプロジェクトなので、
    • 新規立ち上げの際に最初から機能開発に集中できる(認証などは共通化されてるので)
    • 共通化すべきものは common で共通化できる & 依存の方向性を強制できる
    • ライブラリのアップデートを共通で行える(QAの負担減)
    • 1つのエディタで全てのコードにアクセスできる
    • 1発で全てのサーバーを立ち上げられる!
  • サーバー/DBが独立しているので、
    • 独立してデプロイできる
    • 隣のチームの変更とコンフリクトすることがない

今後の課題

一方で課題もあって、

  • 現状エンドポイントが複数に別れてしまっているので、クライアントで切り替えるのが面倒
  • マイクロサービスが増えると、APIの依存の方向性に気をつけないと、デプロイが難しくなる
  • さらにマイクロサービスが増えると、ネットワークがボトルネックになりそう

とはいえ、エンドポイントに関しては Apollo FederationGraphQL Mesh など素晴らしいソリューションがありますし、ネットワークの問題が出てくるのはまだ先の話ということで(日々モニタリングしてますが、パフォーマンスは全然悪くないです)、問題になってから考えるのでも全然遅くないかなと思っています。

まとめ

アルダグラムのマイクロサービス化の現状について、現状の課題も含め赤裸々に書いてみました。
モノリスから移行している途中のリアルを感じていただけたら嬉しいです。

今後も少しずつ改善しながら、より良いプロダクト作りに寄与できる構成に進化させていきます。
プロダクト全体のアーキテクチャを一緒に考えながら開発してくれる仲間を大募集中なので、少しでも興味がある方はぜひお気軽にお声がけください!

アルダグラム Tech Blog

Discussion