こんにちは。エムスリーキャリアでエンジニアをしているakitoshigaです。
近年、疎結合なアーキテクチャの選択肢としてモジュラーモノリスに注目が集まっていますが弊社では保有するプロダクトの1つであるM3Career Primeでモジュラーモノリス化に取り組んでいます。
今回はモジュラーモノリスの概要や採用に至った背景、モジュラーモノリス化における具体的な取り組みの1つであるPackwerkとPacksRailsを導入した話について紹介したいと思います。
M3Career Primeとは
M3career Primeとは、弊社で保有するプロダクトの1つであり医療機関を対象にした医師の採用支援SaaSです。
モジュラーモノリスとは
疎結合なアーキテクチャの1形態であり、単一のコードベースで構成されていますが内部的には機能やビジネスコンテキストの単位で論理的に分割されています。
マイクロサービスと比較して個別のスケーリングやデプロイができないデメリットがあ
りつつも構築や運用コストが低いメリットがあります。
なぜモジュラーモノリス化なのか?
M3Career PrimeはRuby on Railsで構築されています。
当プロダクトはサービスオープン以降度重なる機能の追加や既存機能の改修、さらには本来の機能とは無関係なLP等のサービスも単一のコードベースに追加されるようになってしまい「巨大な泥団子」と化してしまっておりました。
それにより、以下の問題を抱えていました。
- 潜在的な依存関係
- モデルと実装が乖離
- 低凝集・密結合なコード
- 属人化しており、秩序のないコード
その結果として保守性が著しく低下、仕様の調査・見積もり工数の増加、改修に時間がかかるという開発・運用上の課題を抱えていました。
さらに、当プロダクトの構想として今後新たなサービス展開が打ち出されることが予見されていました。
この構想はモジュラーモノリスアーキテクチャと相性が良く、課題解決と今後のサービス展開を見据えて当プロダクトのモジュラーモノリス化を決断しました。
しかし、この決定の前に葛藤もありました。
TechRachoさんが公開されている「素のRailsは十分に豊かである(翻訳)」にもある通り、大規模なサービスでも素のRailsで書かれている事例は存在しています。
個人的にも、前述の問題は非アーキテクチャ依存でありリアーキテクティングまでせずともよりミクロなレベルのリファクタと「Rails Way」の徹底で開発上の課題は解決するのではないかとの思いもありました。
しかし、以下の理由から最終的にはモジュラーモノリスへのリアーキテクティングを実施することを決定しました。
- 個人の経験から、アーキテクチャによる制約を設けた方が保守性を保つことができるのではないかと仮説を立てた。
- 当プロダクトのビジネス的スピード感を考慮した時に、前述の構想に追従するためにはこのタイミングでリアーキテクティングを行うことが最適だと判断した。
Railsのモジュラーモノリスの実装方法にいはくつか種類があるのですが、インクリメンタルに移行出来る点と、前例の多さからPackwerk(+PacksRails)に決定しました。
Packwerkとは
Shopifyが開発しているパッケージ間の依存の静的解析ツールです。
Railsアプリケーション内で論理的な境界を定めることでモジュール化を支援します。
PacksRailsとは
通常のRailsから離れたディレクトリ構成にすることが可能になり、主に物理的なコードベースのモジュール化を支援します。
Packwerkと組み合わせて使用します。
導入した所感
リアーキテクティングにエンジニアの全リソースを注ぎ込めないため、PackwerkとPacksRailsのインクリメンタルに移行出来る点はかなり取り組みやすいと思いました。
PacksRailsを利用すると通常のディレクトリ構成と異なる形で開発をする必要が生じますが、そこまで大きい負荷にはなっていないと感じています。
最後に
現在は試験的に一部の機能を物理的にパッケージ分けした段階であり、これから本格的にモジュラーモノリス化に向けた取り組みを行っていくことになります。
また、モジュラーモノリスアーキテクチャの実現のためにPackwerkとPackRailsの導入以外にもいくつかの施策を実施・検討しています。
これらの取り組みについて、また別の機会でご紹介できればと思います。