ドメイン分析を使用したマイクロサービスのモデル化Using domain analysis to model microservices

マイクロサービスの最大の課題の 1 つは、個々のサービスの境界の定義です。One of the biggest challenges of microservices is to define the boundaries of individual services. 原則として 1 つのサービスは "1 つのこと" を行う必要がありますが、その実現のためには慎重な検討が必要です。The general rule is that a service should do "one thing" — but putting that rule into practice requires careful thought. "適切" な設計を作り出す機械的なプロセスはありません。There is no mechanical process that will produce the "right" design. ビジネス用ドメイン、要件、および目的についてよく考える必要があります。You have to think deeply about your business domain, requirements, and goals. そうしないと、好ましくない特徴 (サービス間の非表示の依存関係、密結合、不完全なデザインのインターフェイスなど) を持つ場当たり的な設計になる可能性があります。Otherwise, you can end up with a haphazard design that exhibits some undesirable characteristics, such as hidden dependencies between services, tight coupling, or poorly designed interfaces. この記事では、マイクロサービスを設計するためのドメイン駆動のアプローチについて説明します。This article shows a domain-driven approach to designing microservices.

この記事では、継続的な例としてドローン配送サービスを使用します。This article uses a drone delivery service as a running example. シナリオおよび対応する参照実装の詳細については、こちらを参照してください。You can read more about the scenario and the corresponding reference implementation here.

はじめにIntroduction

マイクロサービスは、データ アクセスやメッセージングなどの水平レイヤーではなく、ビジネス機能に基づいて設計する必要があります。Microservices should be designed around business capabilities, not horizontal layers such as data access or messaging. また、マイクロサービスには疎結合と機能の高い凝集度が必要です。In addition, they should have loose coupling and high functional cohesion. 他のサービスを同時に更新せずにサービスを変更できる場合、マイクロサービス同士はゆるやかに結び付いています。Microservices are loosely coupled if you can change one service without requiring other services to be updated at the same time. 明確に定義された 1 つの目的 (ユーザー アカウントの管理、配送履歴の追跡など) を持つマイクロサービスは高凝集です。A microservice is cohesive if it has a single, well-defined purpose, such as managing user accounts or tracking delivery history. サービスはドメイン ナレッジをカプセル化し、クライアントからそのナレッジを抽象化する必要があります。A service should encapsulate domain knowledge and abstract that knowledge from clients. たとえば、クライアントは、スケジューリング アルゴリズムの詳細やドローン フリートの管理方法を知らなくてもドローンのスケジュールを設定できる必要があります。For example, a client should be able to schedule a drone without knowing the details of the scheduling algorithm or how the drone fleet is managed.

ドメイン駆動設計 (DDD) は、適切に設計された一連のマイクロサービスを作り出すためのフレームワークを提供します。Domain-driven design (DDD) provides a framework that can get you most of the way to a set of well-designed microservices. DDD には 2 つの異なるフェーズ (戦略と戦術) があります。DDD has two distinct phases, strategic and tactical. 戦略的 DDD では、システムの大規模な構造を定義します。In strategic DDD, you are defining the large-scale structure of the system. 戦略的 DDD は、アーキテクチャがビジネス機能に焦点を当てた状態を維持するために役立ちます。Strategic DDD helps to ensure that your architecture remains focused on business capabilities. 戦術的 DDD は、ドメイン モデルの作成に使うことのできる一連の設計パターンを提供します。Tactical DDD provides a set of design patterns that you can use to create the domain model. これらのパターンには、エンティティ、集約、およびドメイン サービスがあります。These patterns include entities, aggregates, and domain services. このような戦術的パターンを使うと、疎結合および高凝集のマイクロサービスを設計できます。These tactical patterns will help you to design microservices that are both loosely coupled and cohesive.

ドメイン駆動設計 (DDD) プロセスの図

この記事と次の記事では、以下の手順について説明し、それらをドローン配送アプリケーションに適用します。In this article and the next, we'll walk through the following steps, applying them to the Drone Delivery application:

  1. 最初にビジネス用ドメインを分析し、アプリケーションの機能的な要件を理解します。Start by analyzing the business domain to understand the application's functional requirements. この手順により、正式でないドメインの記述が生成されます。この記述をより正式なドメイン モデルのセットに作り替えることができます。The output of this step is an informal description of the domain, which can be refined into a more formal set of domain models.

  2. 次に、ドメインの境界付けられたコンテキストを定義します。Next, define the bounded contexts of the domain. 境界付けられた各コンテキストには、大規模なアプリケーションの特定のサブドメインを表すドメイン モデルが含まれています。Each bounded context contains a domain model that represents a particular subdomain of the larger application.

  3. 境界付けられたコンテキスト内で、戦術的 DDD パターンを適用して、エンティティ、集約、およびドメイン サービスを定義します。Within a bounded context, apply tactical DDD patterns to define entities, aggregates, and domain services.

  4. 前の手順の結果を使って、アプリケーションのマイクロサービスを識別します。Use the results from the previous step to identify the microservices in your application.

この記事では、DDD と主に関連のある最初の 3 つの手順について説明します。In this article, we cover the first three steps, which are primarily concerned with DDD. マイクロサービスの識別は次の記事で行います。In the next article, we'll identify the microservices. ただし、DDD は反復的かつ継続的なプロセスであることを覚えておいてください。However, it's important to remember that DDD is an iterative, ongoing process. サービスの境界は固定されていません。Service boundaries aren't fixed in stone. アプリケーションの進化に伴って、1 つのサービスを複数の小さなサービスに分割することができます。As an application evolves, you may decide to break apart a service into several smaller services.

注意

この記事では、ドメインの完全かつ包括的な分析については説明しません。This article doesn't show a complete and comprehensive domain analysis. 主要なポイントを示すために、あえて簡単な例を取り上げています。We deliberately kept the example brief, to illustrate the main points. DDD の詳しい背景情報については、この用語を最初に紹介した Eric Evans 氏の著書『Domain-Driven Design』をお読みになることをお勧めします。For more background on DDD, we recommend Eric Evans' Domain-Driven Design, the book that first introduced the term. その他の参考資料としては、Vaughn Vernon 氏の著書『Implementing Domain-Driven Design』があります。Another good reference is Implementing Domain-Driven Design by Vaughn Vernon.

シナリオ: ドローン配送Scenario: Drone delivery

Fabrikam, Inc. は、ドローン配送サービスを開始しようとしています。Fabrikam, Inc. is starting a drone delivery service. 同社は、ドローン機団を管理しています。The company manages a fleet of drone aircraft. 企業がサービスに登録すると、ユーザーは、ドローンで商品を集荷して配送するように依頼できます。Businesses register with the service, and users can request a drone to pick up goods for delivery. 顧客が集荷のスケジュールを設定すると、バックエンド システムによってドローンが割り当てられ、推定配送時刻がユーザーに通知されます。When a customer schedules a pickup, a backend system assigns a drone and notifies the user with an estimated delivery time. 配送中、ETA は常時更新され、顧客はドローンの場所を追跡できます。While the delivery is in progress, the customer can track the location of the drone, with a continuously updated ETA.

このシナリオには、かなり複雑なドメインが含まれます。This scenario involves a fairly complicated domain. ビジネスに関する懸念事項には、ドローンのスケジュール設定、荷物の追跡、ユーザー アカウントの管理、履歴データの保存と分析などもあります。Some of the business concerns include scheduling drones, tracking packages, managing user accounts, and storing and analyzing historical data. さらに、Fabrikam が求めているのは、迅速に市場に出し、迅速に反復して、新機能を追加することです。Moreover, Fabrikam wants to get to market quickly and then iterate quickly, adding new functionality and capabilities. アプリケーションは、高いサービス レベル目標 (SLO) に基づいてクラウド スケールで動作する必要があります。The application needs to operate at cloud scale, with a high service level objective (SLO). また、Fabrikam は、システムの部分ごとに、データ ストレージとクエリの要件がまったく異なることを予期しています。Fabrikam also expects that different parts of the system will have very different requirements for data storage and querying. Fabrikam はこれらをすべて考慮した結果、ドローン配送アプリケーションにマイクロサービス アーキテクチャを選択します。All of these considerations lead Fabrikam to choose a microservices architecture for the Drone Delivery application.

ドメインを分析するAnalyze the domain

DDD アプローチを使うと、各サービスがビジネスの機能的な要件に適合するようなマイクロサービスを設計できます。Using a DDD approach will help you to design microservices so that every service forms a natural fit to a functional business requirement. また、組織の境界やテクノロジの選択が設計に影響するというトラップを回避できます。It can help you to avoid the trap of letting organizational boundaries or technology choices dictate your design.

コードを記述する前に、作成するシステムを俯瞰する必要があります。Before writing any code, you need a bird's eye view of the system that you are creating. DDD では、最初にビジネス用ドメインをモデリングして、ドメイン モデルを作成します。DDD starts by modeling the business domain and creating a domain model. ドメイン モデルはビジネス用ドメインの抽象化モデルです。The domain model is an abstract model of the business domain. このモデルはドメイン ナレッジを抽出して整理し、開発者やドメイン エキスパートに共通の言語を提供します。It distills and organizes domain knowledge, and provides a common language for developers and domain experts.

最初に、すべてのビジネス機能とその関係をマッピングします。Start by mapping all of the business functions and their connections. これは、ドメイン エキスパート、ソフトウェア アーキテクト、およびその他の関係者が関与する共同作業になる可能性があります。This will likely be a collaborative effort that involves domain experts, software architects, and other stakeholders. 特定の形式を使う必要はありません。You don't need to use any particular formalism. 図をスケッチするか、ホワイトボードに描画します。Sketch a diagram or draw on whiteboard.

図を描画したら、個別のサブドメインの識別を開始できます。As you fill in the diagram, you may start to identify discrete subdomains. 密接に関連している機能はどれか、Which functions are closely related? ビジネスの中核となる機能はどれか、付帯的なサービスを提供する機能はどれか、Which functions are core to the business, and which provide ancillary services? 依存関係グラフとは何かを確認します。What is the dependency graph? この最初のフェーズでは、テクノロジや実装の詳細を気にすることはありません。During this initial phase, you aren't concerned with technologies or implementation details. とは言え、アプリケーションを外部システム (CRM、支払い処理、請求システムなど) と統合する必要のある場所について注意する必要があります。That said, you should note the place where the application will need to integrate with external systems, such as CRM, payment processing, or billing systems.

例:ドローン配送アプリケーションExample: Drone delivery application

最初のいくつかのドメイン分析の完了後、Fabrikam のチームはドローン配送ドメインを示すおおまかなスケッチを作成しました。After some initial domain analysis, the Fabrikam team came up with a rough sketch that depicts the Drone Delivery domain.

ドローン配送ドメインの図

  • 出荷はビジネスの中核であるため、図の中央に配置します。Shipping is placed in the center of the diagram, because it's core to the business. 図のそれ以外の要素は、この機能を実現するために存在します。Everything else in the diagram exists to enable this functionality.
  • ドローンの管理もビジネスの中核です。Drone management is also core to the business. ドローン管理と密接に関連する機能には、ドローンの修理、および予測分析によるドローンの付帯サービスとメンテナンスが必要な時期の予測があります。Functionality that is closely related to drone management includes drone repair and using predictive analysis to predict when drones need servicing and maintenance.
  • ETA 分析は集配の時間を見積もります。ETA analysis provides time estimates for pickup and delivery.
  • サード パーティの輸送では、荷物をドローンで出荷できない場合の代替輸送方法をアプリケーションでスケジュールできます。Third-party transportation will enable the application to schedule alternative transportation methods if a package cannot be shipped entirely by drone.
  • ドローンの共有は、コア ビジネスを拡張するものです。Drone sharing is a possible extension of the core business. 企業では、ドローンが空きがある期間に、使われていないドローンを貸し出すことができます。The company may have excess drone capacity during certain hours, and could rent out drones that would otherwise be idle. この機能は、初期リリースには含まれていません。This feature will not be in the initial release.
  • ビデオ監視は、企業が後から展開する可能性のあるもう 1 つの分野です。Video surveillance is another area that the company might expand into later.
  • ユーザー アカウント請求、およびコール センターは、コア ビジネスをサポートするサブドメインです。User accounts, Invoicing, and Call center are subdomains that support the core business.

プロセスのこの時点では、実装やテクノロジに関する決定を行っていません。Notice that at this point in the process, we haven't made any decisions about implementation or technologies. 一部のサブシステムには、外部のソフトウェア システムやサード パーティのサービスが含まれている可能性があります。Some of the subsystems may involve external software systems or third-party services. その場合でも、アプリケーションはこれらのシステムやサービスとやり取りする必要があるため、ドメイン モデルにシステムやサービスを追加することが重要です。Even so, the application needs to interact with these systems and services, so it's important to include them in the domain model.

注意

アプリケーションが外部システムに依存する場合は、外部システムのデータ スキーマや API がアプリケーションに漏えいし、最終的にアーキテクチャの設計が損なわれるというリスクがあります。When an application depends on an external system, there is a risk that the external system's data schema or API will leak into your application, ultimately compromising the architectural design. これは、最新のベスト プラクティスに従っていない、および複雑なデータ スキーマや古い API を使っている従来のシステムに特に当てはまります。This is particularly true with legacy systems that may not follow modern best practices, and may use convoluted data schemas or obsolete APIs. その場合は、これらの外部システムとアプリケーション間の境界を明確に定義することが重要です。In that case, it's important to have a well-defined boundary between these external systems and the application. そのためには、ストラングラー パターンまたは破損対策レイヤー パターンの使用を検討してください。Consider using the Strangler pattern or the Anti-Corruption Layer pattern for this purpose.

境界付けられたコンテキストを定義するDefine bounded contexts

ドメイン モデルには、世界中に存在する実際のもの (ユーザー、ドローン、荷物など) の表現が含まれます。The domain model will include representations of real things in the world — users, drones, packages, and so forth. ただし、同じものについてシステム全体で同じ表現を使わなければならないというわけではありません。But that doesn't mean that every part of the system needs to use the same representations for the same things.

たとえば、ドローンの修理と予測分析を扱うサブシステムでは、ドローンの多くの物理的特性 (メンテナンス履歴、マイレージ、年数、モデル番号、性能の特徴など) を表す必要があります。For example, subsystems that handle drone repair and predictive analysis will need to represent many physical characteristics drones, such as their maintenance history, mileage, age, model number, performance characteristics, and so on. しかし、配送をスケジュールするときは、それらについて考慮しません。But when it's time to schedule a delivery, we don't care about those things. スケジューリング サブシステムでは、ドローンが使用可能か、および集配の ETA だけを把握する必要があります。The scheduling subsystem only needs to know whether a drone is available, and the ETA for pickup and delivery.

これらの 2 つのサブシステムに対して 1 つのモデルを作成しようとすると、不必要に複雑なモデルになります。If we tried to create a single model for both of these subsystems, it would be unnecessarily complex. また、変更を行う場合に複数のチームが個々のサブシステムに対して作業を行う必要があるため、時間の経過と共にモデルの進化が難しくなります。It would also become harder for the model to evolve over time, because any changes will need to satisfy multiple teams working on separate subsystems. そのため、多くの場合、現実世界のエンティティ (ここではドローン) を 2 つの異なるコンテキストで表す個別のモデルを設計することをお勧めします。Therefore, it's often better to design separate models that represent the same real-world entity (in this case, a drone) in two different contexts. 各モデルには、特定のコンテキスト内に関連する機能と属性だけが含まれます。Each model contains only the features and attributes that are relevant within its particular context.

ここで、境界付けられたコンテキストという DDD の概念が作用します。This is where the DDD concept of bounded contexts comes into play. 境界付けられたコンテキストは、特定のドメイン モデルが適用されるドメイン内の単なる境界です。A bounded context is simply the boundary within a domain where a particular domain model applies. 前述の図では、さまざまな機能が 1 つのドメイン モデルを共有するかどうかに従って機能をグループ化できます。Looking at the previous diagram, we can group functionality according to whether various functions will share a single domain model.

境界付けられたコンテキストの図

境界付けられたコンテキストは、必ずしも互いに分離された状態である必要はありません。Bounded contexts are not necessarily isolated from one another. この図では、境界付けられたコンテキストを結ぶ実線は、2 つの境界付けられたコンテキストがやり取りする場所を表します。In this diagram, the solid lines connecting the bounded contexts represent places where two bounded contexts interact. たとえば、"出荷" は顧客の情報を取得するために "ユーザー アカウント" に依存し、フリートのドローンをスケジュールするために "ドローン管理" に依存します。For example, Shipping depends on User Accounts to get information about customers, and on Drone Management to schedule drones from the fleet.

Eric Evans 氏は、著書『Domain Driven Design』で、別の境界付けられたコンテキストとやり取りする際にドメイン モデルの整合性を維持するための複数のパターンについて説明しています。In the book Domain Driven Design, Eric Evans describes several patterns for maintaining the integrity of a domain model when it interacts with another bounded context. マイクロサービスの主要な原則の 1 つは、明確に定義された API を通じてサービスがやり取りするということです。One of the main principles of microservices is that services communicate through well-defined APIs. このアプローチは、Evans 氏が Open Host Service および Published Language と呼ぶ 2 つのパターンに対応します。This approach corresponds to two patterns that Evans calls Open Host Service and Published Language. Open Host Service では、サブシステムが他のサブシステムとやり取りするための正式なプロトコル (API) を定義します。The idea of Open Host Service is that a subsystem defines a formal protocol (API) for other subsystems to communicate with it. Published Language は、他のチームがクライアントを記述するために使うことのできる形式で API を発行することにより、この考え方を拡張したものです。Published Language extends this idea by publishing the API in a form that other teams can use to write clients. Designing APIs for microservices」(マイクロサービス用 API の設計) の記事では、OpenAPI 仕様 (旧称 Swagger) を使って、JSON または YAML 形式で表現された、REST API 用の言語に依存しないインターフェイスの記述を定義する方法について説明します。In the article Designing APIs for microservices, we discuss using OpenAPI Specification (formerly known as Swagger) to define language-agnostic interface descriptions for REST APIs, expressed in JSON or YAML format.

この記事の以降の部分では、境界付けられたコンテキスト "出荷" について重点的に説明します。For the rest of this journey, we will focus on the Shipping bounded context.

次の手順Next steps

ドメイン分析の完了後、次の手順では戦術的 DDD を適用して、より高い精度でドメイン モデルを定義します。After completing a domain analysis, the next step is to apply tactical DDD, to define your domain models with more precision.