モノリシックアプリケーションからマイクロサービスへのリファクタリング

GMOアドマーケティングのT.Oです。今回は以下の書籍、および同じ著者によるサイトの内容をもとに「モノリシックアプリケーションからマイクロサービスへのリファクタリング」についてご紹介します。

書籍
    『実践的システムデザインのためのコード解説 マイクロサービスパターン』
    Chris Richardson(著)
    長尾 高弘(訳)
    樽澤 広亨(監修)
サイト
 microservices.io, 「What are microservices?」, https://microservices.io/index.html, (参照 2023-07-12)

1.モノリシックアプリケーションとは

モノリシックアプリケーションとは分割されていない1つのモジュール(ファイル)から構成されたアプリケーションのことです。
アプリケーションの規模が小さいうちは、モノリシックアプリケーションには以下のような利点があります。

・開発しやすい
・大きな変更を加えやすい
・テストしやすい
・デプロイしやすい

・スケーリングが難しい

以下の図はモノリシックアプリケーションによる注文、発送管理を行なうためのアプリケーションの例です。

モノリシックアプリケーションの欠点

規模が小さい場合には利点のあったモノリシックアプリケーションですが、時間の経過とともにアプリケーションサイズが大きく複雑になり、以下のような多くの問題が発生するようになります。

・コミットから本番デプロイまで道のりが長く険しい・・・すべての開発チームが1つのコードベースに関わるので、コミュニケーションや調整のオーバーヘッドが生まれます。またマージに時間がかかったり、ビルドがリリース不能な状態になることが多くなります。
・複雑なシステムに開発者が萎縮する・・・規模が大きすぎるため全体の機能を完全に理解することができなくなります。このため信頼性が低くなりがちでメンテナンスが困難になります。
・開発ペースが遅い・・・ビルドが遅くなり、編集-ビルド-実行-テストのループにかかる時間が長くなり生産性が低下します。
・スケーリングが難しい・・・アプリケーションを構成するモジュールごとに必要なリソースの要件が矛盾することがありえます。あるモジュールでは大量のメモリを使用したいのですが、別のモジュールではメモリではなくCPUが多数あった方が良いなどのケースです。このような場合にはサーバーの構成で妥協を強いられます。
・陳腐化していく技術スタックに縛りつけられる・・・技術スタックとはプログラミング言語、フレームワーク、ライブラリ、ツールなどの組み合わせのことで効率的にソフトウェアを構築することを可能にするものです。モノリシックアプリケーションでは単一の技術スタックを使用します。別の技術スタックを採用する場合、アプリケーション全体の変更が必要になります。このため変更がしづらく、次第に陳腐化する技術スタックに縛り付けられるようになります。

2.マイクロサービスとは

マイクロサービスは、ソフトウェア開発アーキテクチャの一種です。アプリケーションを複数の小さな独立したサービスに分割します。
各サービスは特定の機能を提供し、個別に開発・デプロイ・拡張・管理できます。
それぞれのサービスは独立して動作し、別のデータベースを利用します。他のサービスのデータベースを直接参照することはできず、通信手段(通常はAPI)を介して他のサービスと連携します。
このアプローチにより、アプリケーション全体を柔軟かつスケーラブルに構築できるようになります。

なお複数のマイクロサービス間をまたがるトランザクションを実現したい場合、複数のデータベースの更新が必要になりますので、データベース自体のトランザクション機能を利用することができません。
この問題に対応するためのアーキテクチャパターンがいくつかありますが、代表的なパターンの一つとしてサーガパターンがあります。
サーガパターンは一部のデータベースの更新処理が失敗した場合、それよりも前に実行完了したデータベースの更新処理についても取り消す「補償トランザクション」を使って整合性を保つアーキテクチャパターンです。

以下の図はモノリシックプレイケーションの例であげた電子商取引のアプリケーションをマイクロサービス化した例です。

マイクロサービスの利点

マイクロサービスには以下のような利点があります。

・柔軟性と独立性・・・各サービスは独自のコードベースを持ち、独立して開発・デプロイできます。このため、特定のサービスの変更やスケールアップが容易になります。
・スケーラビリティ・・・マイクロサービスは個別にスケーリングできるため、必要なサービスのみをスケールアップできます。これにより、リソースの効率的な利用が可能になります。
・技術スタックの多様性・・・各サービスは独自の技術スタックを使用できます。開発者は最適なツールやプログラミング言語を選択できるため、特定の要件に最適な技術を採用できます。
・分散開発とチームの効率化・・・マイクロサービスアーキテクチャでは、複数の小規模な開発チームが各サービスに専念できます。これにより、開発スピードが向上し、異なるサービスを担当するチームが同時並行で作業できます。

マイクロサービスの欠点

マイクロサービスには以下のような欠点や問題点があります。

・サービスの適切な分割方法を見つけるのが難しい。
・分散システムは複雑で、開発/テスト/デプロイが難しい。
・複数のサービスにまたがって使われる機能のデプロイを行うには調整が必要になる。
・いつマイクロサービスアーキテクチャを採用すべきか判断が難しい。
・マイクロサービス実装のための学習コストが高い。

3.モノリシックアプリケーションからマイクロサービスへのリファクタリング

既存のサービスを包囲するように、マイクロサービスから構成される「ストラングラーアプリケーション」に移行していく方法がおすすめされています。この方法ではモノリシックアプリケーションを構成するモジュールを段階的に抽出し、抽出したモジュールをマイクロサービスにリファクタリングします。

以下の図のようにリファクタリングが進むにつれて、段階的にモノリシック側は小さくなり、最終的には存在しなくなります。

モノリシックからマイクロサービスへのリファクタリング例

以下の例では注文、配送管理を行うためのモノリシックアプリケーションから配送管理のモジュールを抽出し、マイクロサービスにリファクタリングします。説明図では「モノリシックアプリケーション」を「モノリス」、「マイクロサービス」を「サービス」と略しています。
なお本例は以下のサイトのページを参照し、執筆者が翻訳した内容となっています。

microservice.io, 「Example of extracting a service from monolith」, https://microservices.io/refactoring/example-of-extracting-a-service.html, (参照 2023-07-12)
1.コードを分割し、配送管理をモノリス内の個別の疎結合モジュールに変換します。
2.データベースを分割し、配送管理用に別のスキーマを定義します。
インテグレーショングルーは、モノリシックアプリケーションとマイクロサービスを連携させるための仕組みです。
この例の場合、RESTとドメインイベント、データベースのレプリケーションを使って連携を行います。
3.スタンドアローンの配信サービスを定義します。
この段階では配送管理のクライアントはモノリス側の配送管理機能を利用します。
4.スタンドアローンの配信マイクロサービスを使用します。
配送管理のクライアントはモノリスの配送管理ではなく、配送サービスをAPIゲートウェイを介して利用します。また注文管理のクライアントに関してもモノリスの注文管理を直接利用するのではなく、APIゲートウェイを介して利用するよう変更します。配送サービスのデータはモノリスとの間に追加したインテグレーショングルーを介して取得、更新を行なうよう変更します。
5.使用しなくなった配送管理機能をモノリシックアプリケーションから削除します。

ここまでの変更で配送管理機能を配送マイクロサービスにリファクタリングすることができました。
配送マイクロサービス側に「配送管理のデータベース」を移行しましたので、元のモノリスの「注文、配送管理のデータベース」については、配送管理分のデータを削除し「注文管理のデータベース」に変更します。

4.まとめ

「モノリシックアプリケーションからマイクロサービスへのリファクタリング」をご紹介しました。
今回の内容が皆さんのお役に立てれば幸いです。