ドメイン駆動設計パターンを使用してモノリスからマイクロサービスへMonoliths to microservices using domain-driven design

この記事では、ドメイン駆動設計 (DDD) を使用してモノリシック アプリケーションをマイクロサービスに移行する方法について説明します。This article describes how to use domain-driven design (DDD) to migrate a monolithic application to microservices.

モノリシック アプリケーションは、通常、関連するすべてのモジュールが 1 つのデプロイ可能な実行単位としてパッケージ化されているアプリケーション システムです。A monolithic application is typically an application system in which all of the relevant modules are packaged together as a single deployable unit of execution. たとえば、Tomcat で実行されている Java Web アプリケーション (WAR) または IIS で実行されている ASP .NET アプリケーションである場合があります。For example, it might be a Java Web Application (WAR) running on Tomcat or an ASP.NET application running on IIS. 一般的なモノリシック アプリケーションでは、UI、アプリケーション ロジック、およびデータ アクセス用に別個のレイヤーがある、複数層の設計を使用します。A typical monolithic application uses a layered design, with separate layers for UI, application logic, and data access.

一般的なモノリス アーキテクチャ

これらのシステムは最初は小規模ですが、ビジネス ニーズを満たすために時間の経過と共に増加する傾向があります。These systems start small but tend to grow over time to meet business needs. ある時点で新しい機能が追加されると、モノリシック アプリケーションでは以下の問題が発生し始める可能性があります。At some point, as new features are added, a monolithic application can begin to suffer from the following problems:

  • システムの個々の部分が密接に結合されているため、個別にスケールすることができない。The individual parts of the system cannot be scaled independently, because they are tightly coupled.
  • 密結合と隠れた依存関係が原因で、コードを維持するのが難しい。It is hard to maintain the code, because of tight coupling and hidden dependencies.
  • テストが難しくなるほど、脆弱性が発生する可能性が高くなる。Testing becomes harder, increasing the probability of introducing vulnerabilities.

これらの問題は、将来の成長と安定性に対する障害になる可能性があります。These problems can become an obstacle to future growth and stability. チームは、最初の開発者がプロジェクトに従事しなくなっていて、設計ドキュメントがわずかしかなかったり古くなったりしている場合は特に、変更を加えることに慎重になります。Teams become wary of making changes, especially if the original developers are no longer working on the project and design documents are sparse or outdated.

これらの制限にもかかわらず、モノリシック設計はアプリケーションの開始点としては理にかなっている可能性があります。Despite these limitations, a monolithic design can make sense as a starting point for an application. 多くの場合、モノリスは、概念実証または実用最小限の製品を構築するための最も簡単なパスです。Monoliths are often the quickest path to building a proof-of-concept or minimal viable product. 開発の初期段階では、モノリスには次のような傾向があります。In the early phases of development, monoliths tend to be:

  • ビルドがより簡単である (1 つの共有コード ベースがあるため)。Easier to build, because there is a single shared code base.
  • デバッグがより簡単である (コードが 1 つのプロセスとメモリ空間内で実行されるため)。Easier to debug, because the code runs within a single process and memory space.
  • より簡単に理解できる (移動するパーツが少ないため)。Easier to reason about, because there are fewer moving parts.

ただし、アプリケーションの複雑さが増すにつれて、これらの利点がなくなる可能性があります。As the application grows in complexity, however, these advantages can disappear. 多くの場合、大規模なモノリスは、ビルド、デバッグ、および理解が徐々に難しくなります。Large monoliths often become progressively harder to build, debug, and reason about. ある時点で、これらの問題が利点を上回ります。At some point, the problems outweigh the benefits. これが、アプリケーションをマイクロサービス アーキテクチャに移行することが理にかなうタイミングです。This is the point when it can make sense to migrate the application to a microservices architecture. モノリスとは異なり、マイクロサービスは、通常は分散型で疎結合の実行単位です。Unlike monoliths, microservices are typically decentralized, loosely coupled units of execution. 次の図は、一般的なマイクロサービスのアーキテクチャを示しています。The following diagram shows a typical microservices architecture:

一般的なマイクロサービス アーキテクチャ

モノリスをマイクロサービスに移行するには、エラーやオーバーランを回避するためにかなりの時間と投資が必要です。Migrating a monolith to a microservice requires significant time and investment to avoid failures or overruns. 移行が確実に行われるようにするには、利点と、マイクロサービスによってもたらされる課題を、両方とも理解しておくことをお勧めします。To ensure that any migration is successful, it's good to understand both the benefits and also challenges that microservices bring. 次の利点があります。The benefits include:

  • サービスは、ユーザーのニーズに基づいて独立して進化できます。Services can evolve independently based on user needs.
  • サービスは、ユーザーの要求に合わせて独立してスケールできます。Services can scale independently to meet user demand.
  • 時間が経つにつれて、機能をより早く市場にリリースできるようになるため、開発サイクルが速くなります。Over time, development cycles become faster as features can be released to market quicker.
  • サービスは分離されており、障害に対してより耐性があります。Services are isolated and are more tolerant of failure.
  • 1 つのサービスで障害が発生しても、アプリケーション全体が停止することはありません。A single service that fails will not bring down the entire application.
  • ビヘイビア駆動開発を使用すると、テストの一貫性と整合性が向上します。Testing becomes more coherent and consistent, using behavior-driven development.

マイクロサービスの利点と課題の詳細については、「マイクロサービス アーキテクチャ スタイル」を参照してください。For more information about the benefits and challenges of microservices, see Microservices architecture style.

ドメイン駆動設計の適用Apply domain-driven design

移行戦略では、チームがアプリケーションをより小さなサービスに段階的にリファクタリングしながら、エンド ユーザーにサービスの継続性を提供できるようにする必要があります。Any migration strategy should allow teams to incrementally refactor the application into smaller services, while still providing continuity of service to end users. 一般的なアプローチを次に示します。Here's the general approach:

  • モノリスへの機能の追加を停止します。Stop adding functionality to the monolith.
  • フロントエンドからバックエンドを分割します。Split the front end from the back end.
  • モノリスを分解し、一連のマイクロサービスに分離します。Decompose and decouple the monolith into a series of microservices.

この分解を容易にするために、実用的なソフトウェア開発アプローチは、ドメイン駆動設計 (DDD) の原則を適用することです。To help facilitate this decomposition, a viable software development approach is to apply the principles of domain-driven design (DDD).

ドメイン駆動設計 (DDD) は、Eric Evans によって最初に導入されたソフトウェア開発アプローチです。Domain Driven Design (DDD) is a software development approach first introduced by Eric Evans. DDD では、アプリケーションが記述されるドメインについて十分に理解している必要があります。DDD requires a good understanding of the domain for which the application will be written. アプリケーションを作成するために必要なドメイン ナレッジは、それを理解している人、つまりドメインの専門家の中に存在します。The necessary domain knowledge to create the application resides within the people who understand it — the domain experts.

DDD アプローチは、アプリケーションの分解を開始する手段として、既存のアプリケーションにさかのぼって適用することができます。The DDD approach can be applied retroactively to an existing application, as a way to begin decomposing the application.

  1. すべての利害関係者の間で共有される一般的な語彙である、ユビキタス言語から始めます。Start with a ubiquitous language, a common vocabulary that is shared between all stakeholders.

  2. モノリシック アプリケーションで関連するモジュールを特定し、それらに共通の語彙を適用します。Identify the relevant modules in the monolithic application and apply the common vocabulary to them.

  3. モノリシック アプリケーションのドメイン モデルを定義します。Define the domain models of the monolithic application. ドメイン モデルはビジネス用ドメインの抽象化モデルです。The domain model is an abstract model of the business domain.

  4. モデルの境界付けられたコンテキストを定義します。Define bounded contexts for the models. 境界付けられたコンテキストは、特定のドメイン モデルが適用されるドメイン内の境界です。A bounded context is the boundary within a domain where a particular domain model applies. モデルと責任が明確に定義された、明示的な境界を適用します。Apply explicit boundaries with clearly defined models and responsibilities.

手順 4 で特定された境界付けられたコンテキストは、小規模なマイクロサービスにリファクタリングするための候補です。The bounded contexts identified in step 4 are candidates for refactoring into smaller microservices. 次の図は、境界付けられたコンテキストが重なっている既存のモノリスを示しています。The following diagram shows the existing monolith with the bounded contexts overlaid:

モノリス内の境界付けられたコンテキスト

マイクロサービス アーキテクチャのための DDD アプローチの使用の詳細については、「ドメイン分析を使用したマイクロサービスのモデル化」をご覧ください。For more information about using a DDD approach for microservices architectures, see Using domain analysis to model microservices.

グルー コードの使用 (破損対策レイヤー)Use glue code (anti-corruption layer)

この調査作業はモノリシック アプリケーションのインベントリを作成するために行われますが、DDD の原則を個別のサービスとして適用することで、新しい機能を追加することができます。While this investigative work is carried out to inventory the monolithic application, new functionality can be added by applying the principles of DDD as separate services. "グルー コード" を使用すると、モノリシック アプリケーションで新しいサービスへの呼び出しをプロキシして、新しい機能を取得することができます。"Glue code" allows the monolithic application to proxy calls to the new service to obtain new functionality.

 モノリスが新しいサービスと対話できるようにするグルー コードGlue Code to allow a monolith to interact with a new service

グルー コード (アダプター パターン) は、破損対策レイヤーとして効果的に機能し、モノリシック アプリケーションで必要とされるデータ モデルによって新しいサービスが汚染されされないようにします。The glue code (adapter pattern) effectively acts as an anti-corruption layer, ensuring that the new service is not polluted by data models required by the monolithic application. グルー コードは、この 2 つの間の相互作用を仲介し、互換性を確保するために、新しいサービスが必要とするデータだけが渡されるようにします。The glue code helps to mediate interactions between the two and ensures that only data required by the new service is passed to enable compatibility.

チームは、リファクタリングのプロセスを通じてモノリシック アプリケーションのインベントリを作成し、マイクロサービス リファクタリングの候補を特定しながら、新しいサービスを使用して新しい機能を確立することができます。Through the process of refactoring, teams can inventory the monolithic application and identify candidates for microservices refactoring while also establishing new functionality with new services.

破損対策レイヤーの詳細については、「破損対策レイヤー パターン」を参照してください。For more information about anti-corruption layers, see Anti-Corruption Layer pattern.

プレゼンテーション層の作成Create a presentation layer

次の手順では、バックエンド層からプレゼンテーション層を分離します。The next step is to separate the presentation layer from the backend layer. 従来の n 層アプリケーションでは、アプリケーション (ビジネス) 層はアプリケーションの中核となるコンポーネントであり、その中にドメイン ロジックがある傾向があります。In a traditional n-tier application, the application (business) layer tends to be the components that are core to the application and have domain logic within them. これらの粒度の粗い API は、データ アクセス層を操作して、データベース内から持続的なデータを取得します。These coarse-grained APIs interact with the data access layer to retrieve persisted data from within a database. これらの API は、プレゼンテーション層への自然な境界を確立し、プレゼンテーション層を別のアプリケーション領域に分離するのに役立ちます。These APIs establish a natural boundary to the presentation tier, and help to decouple the presentation tier into a separate application space.

次の図は、アプリケーション ロジックとデータ アクセス層から分割されたプレゼンテーション層 (UI) を示しています。The follow diagram shows the presentation layer (UI) split out from the application logic and data access layers.

API ゲートウェイ パターン

この図では、プレゼンテーション層とアプリケーション ロジックの間に配置される別のレイヤーである、API ゲートウェイも導入されています。This diagram also introduces another layer, the API gateway, that sits between the presentation layer and the application logic. API ゲートウェイは、アプリケーションに影響を与えずに、下流のサービスを独立して進化させながら、プレゼンテーション層と対話するための一貫した統一されたインターフェイスを提供するファサード層です。The API gateway is a façade layer that provides a consistent and uniform interface for the presentation layer to interact with, while allowing downstream services to evolve independently, without affecting the application. API ゲートウェイでは、Azure API Management などのテクノロジを使用して、アプリケーションが RESTful 方式で対話できるようにすることができます。The API Gateway may use a technology such as Azure API Management, and allows the application to interact in a RESTful manner.

プレゼンテーション層は、シングル ページ アプリケーションや MVC アプリケーションなど、チームが専門知識を持つ任意の言語またはフレームワークで開発できます。The presentation tier can be developed in any language or framework that the team has expertise in, such as a single page application or an MVC application. これらのアプリケーションは、標準の HTTP 呼び出しを使用して、ゲートウェイ経由でマイクロサービスとやり取りします。These applications interact with the microservices via the gateway, using standard HTTP calls. API ゲートウェイの詳細については、「マイクロサービスでの API ゲートウェイの使用」を参照してください。For more information about API Gateways, see Using API gateways in microservices.

モノリスの廃止を開始するStart to retire the monolith

この段階で、チームはモノリシック アプリケーションを剥がし始め、境界付けされたコンテキストによって確立されたサービスを独自のマイクロサービスのセットに徐々に抽出することができます。At this stage, the team can begin peeling away the monolithic application and slowly extract the services that have been established by their bounded contexts into their own set of microservices. マイクロサービスは、特定の状況でモノリスと通信するためのグルー コードを使用して、API ゲートウェイ経由でアプリケーション層とやり取りするための RESTful インターフェイスを公開できます。The microservices can expose a RESTful interface for the application layer to interact with, through the API gateway, with glue code in place to communicate with the monolith in specific circumstances.

API 層の使用

モノリスを剥がし続けて、最終的に存在する必要がなくなったときには、マイクロサービスがモノリスから正常に抽出されています。As you continue to peel away the monolith, eventually there will come the point when it no longer needs to exist, and the microservices have been successfully extracted from the monolith. この時点で、破損対策レイヤー (グルー コード) を安全に削除できます。At this point, the anti-corruption layer (glue code) can safely be removed.

このアプローチはストラングラー パターンの一例であり、マイクロサービスのセットへのモノリスの制御された分解を可能にします。This approach is an example of the Strangler pattern and allows for a controlled decomposition of a monolith into a set of microservices. 時間とともに、既存の機能がマイクロサービスに移行されるにつれて、モノリスは、存在しなくなるまでサイズと複雑さが縮小されていきます。Over time, as existing functionality is moved into microservices, the monolith will shrink in size and complexity, to the point that it no longer exists.

次のステップNext steps

アプリケーションが構成要素であるマイクロサービスに分解されると、Azure DevOps などの最新のオーケストレーション ツールを使用して、各サービスのライフサイクルを管理できるようになります。When the application has been decomposed into constituent microservices, it becomes possible to use modern orchestration tools such as Azure DevOps to manage the lifecycle of each service. 詳細については、マイクロサービス アーキテクチャの CI/CD に関するページを参照してください。For more information, see CI/CD for microservices architectures.