モジュラモノリスからモノリスへ。RemitAid の Go アプリケーションアーキテクチャと課題
こんにちは!ソフトウェアエンジニアの inari111 です。
弊社はバックエンドに Go を使っています。
本記事では Go アプリケーションのアーキテクチャについて書きたいと思います。
Go アプリケーションのアーキテクチャ
弊社の Go アプリケーションはモジュラモノリスをクリーンアーキテクチャで実装しています。
merchant モジュール と transfer モジュールがあり、composer という各モジュールを取りまとめる usecase レイヤーから各モジュールに接続する構成になっています。そして merchant モジュールは merchant DB、transfer モジュールは transfer DB に接続しています。

約 3 年間モジュラモノリスのアプリケーションとして開発されてきました。
モジュラモノリスのメリットを享受しつつ走り続けた 3 年間だったのですが、だんだんデメリットも増えてきました。
問題点
先述の通り、デメリットに感じることがだんだん増えてきました。
モジュラモノリスやクリーンアーキテクチャのデメリットというよりは、弊社の今のサービスのフェーズには合わないなと感じるようになってきたので、いくつか挙げたいと思います。
1 つ目は、レイヤーが多く触るファイルが多いことです。
個人的にはレイヤードアーキテクチャは好きですが、今の私たちの構成は少々レイヤーが多いと感じています。
モジュラモノリスをクリーンアーキテクチャで実装した結果、重厚感のある実装になってしまったと考えています。
FinTech のサービスなので堅牢に作っていきたいのですが、チームとしてどのくらいスピード感を持って開発を進めていけるかはとても大切です。
レイヤーが多いことで書くコード量も増えます。レイヤーを分けることで関心事の分離ができることはメリットですが、開発スピードの低下をデメリットとして感じています。
2 つ目は、各モジュールの境界が曖昧でモジュラモノリスとして成立していないことです。
merchant DB と transfer DB の境界が曖昧になってしまったことに伴い、各モジュールの境界も曖昧になってしまっています。
理由はいろいろあったと推測しているのですが、ピボットしたりサービスが増えていく等、流れが速い中で、最初からモジュラモノリスで開発するのは難易度が高かったかなと考えています。
3 つ目は、トランザクション境界です。
merchant DB と transfer DB の境界が曖昧になってしまったことにより、同一トランザクションで処理したいにもかかわらず、それができないという問題も発生しています。
どのように解決するか
結論として、merchant DB と transfer DB を 1 つの DB に統合し、モジュラモノリスからモノリスへ徐々に移行していくことにしました。
理由としては、merchant DB と transfer DB の境界が曖昧で密結合になっていること、現時点ではモジュールをきれいに分割しながら開発を進めることが難しいからです。
密結合のまま進み続けて認知負荷を上げるよりもシンプルな構成に寄せ、チームとしての開発スピードを上げるのが狙いです。
また、弊社のエンジニアは 4 人なので、モノリスで開発しても困ることが少なく、体験がいいのではないかと考えています。
サービスが成長しエンジニアの人数が増えてきて問題が見えてきたタイミングで、モジュラモノリスなのか、別のアーキテクチャなのかはまだわかりませんが、変えていきたいです。
現在、DB 統合に向けて対応中です。
DB統合後のイメージはこちらです。
merchant DB と transfer DB を 統合し、各モジュールからも一旦 composer DB に接続します。

モジュラモノリスからモノリスへ移行後のイメージはこちらです。
各モジュールが消え、composer から composer DB へ接続します。
composer はシンプルなレイヤードアーキテクチャで構成します。

おわりに
現在の Go アプリケーションのアーキテクチャの紹介と問題点、問題点をどう解決するかについて紹介しました。
長期的に見て今やっておくべき課題の解決は進めていき、チーム全体としてのアウトプットを高めていけたらと思います。
RemitAid では一緒に働く仲間を募集しています。
1 人目カスタマーサクセスの募集を開始しました。
興味がある方はこちらからどうぞ!
Discussion