コンテンツにスキップ

マイクロサービス設計@マイクロサービス領域

はじめに

本サイトにつきまして、以下をご認識のほど宜しくお願いいたします。


01. ドメイン層

マイクロサービス

▼ マイクロサービスとは

anti-corruption-layer

マイクロサービスアーキテクチャにおける分散システム状のバックエンドのコンポーネントのこと。

特定のマイクロサービスが他のマイクロサービスに侵食され、マイクロサービスの凝集度が低くならないようにするために、ACL:Anti Corruption Layer (腐食防止レイヤー) を設ける必要がある。

腐食防止レイヤーは、異なるコンテキストから受信したデータを、そのマイクロサービスのコンテキストにあったデータ形式に変換する責務を持つ。

CQRSでは、これはプロセスマネージャパターンとして知られている。

一方でSagaパターンとも呼ばれるが、分散トランザクションでも同じ用語があるため、混乱を避けるためにプロセスマネージャパターンとする。

▼ 各マイクロサービスのアーキテクチャ

各マイクロサービスのアーキテクチャは自由である。

この時、ドメイン駆動設計のアーキテクチャを基に実装できる。

*例*

ECサイトがあり、これの商品販売ドメインを販売サブドメインと配送サブドメインに分割できるとする。

この時、それぞれのサブドメインの問題を解決する販売コンテキストと配送コンテキストをマイクロサービスの粒度となり、オニオンアーキテクチャのアプリケーション間で同期通信/非同期通信を実行する。

microservices-architecture_onion-architecture


分割パターン

▼ サブドメイン単位/境界づけられたコンテキスト単位

サブドメインまたは境界づけられたコンテキストを単位として、マイクロサービスを分割とする。

現状のモノリスの分割段階 境界づけられたコンテキスト サブドメイン 機能単位
すでにサブドメインに分割されている 不可 不可 記入中...
すでに複数のサブドメインを含む境界づけられたコンテキストに分割されている 不可 記入中...
すでに単一のサブドメインを含む境界づけられたコンテキストに分割されている 記入中...

解決領域となる境界づけられたコンテキストがサブドメインの中に1個しか含まれていない場合は、境界づけられたコンテキストでマイクロサービスを分割することになる。

図にて、境界づけられたコンテキスト間で、『利用者』という名詞に対する定義づけ/意味合いが異なっていることに留意する。

ドメイン駆動設計では境界づけられたコンテキストが1個のアプリケーションに相当するため、境界づけられたコンテキストで分割した場合、マイクロサービスアーキテクチャは複数のアプリケーションから構成されるアーキテクチャと捉えられる。

加えて小さな粒度に分割する方法として、ルートエンティティを粒度ともできる。

service_bounded-context

▼ ルートエンティティ単位 (エンティティサービス)

『エンティティサービス』ともいう。

ドメイン層のルートエンティティを単位として、マイクロサービスを分割する。

この場合、境界づけられたコンテキストよりもマイクロサービスの粒度が小さい。

そのため、複数のマイクロサービスで1つの境界づけられたコンテキストを構成することになり、異なるマイクロサービスが同じ種類のデータを持つオブジェクトを処理する。

ドメイン層にはマイクロサービス (例:〇〇ドメインサービス) があり、ドメイン層以外のレイヤー (インターフェース層、ユースケース層、リポジトリ層) はマイクロサービスではない。

DBレコードの書き込み/読み出しのトランザクションをルートエンティティ単位で実行するため、マイクロサービスの単位がわかりやすい。

一方で、データに着目したステートソーシングパターンのルートエンティティを使用することはアンチパターンである。

最良な解決策として、振舞に着目したイベントソーシングを使用する必要がある。

また、各マイクロサービスを名詞ではなく動詞 (例:〇〇管理サービス、〇〇中継サービス、〇〇通知サービス、〇〇集計サービス) で命名すると良い。

その他、各マイクロサービスでDBを完全に独立させることや、SAGAパターンを使用すること、がある。


分割アンチパターン

▼ 分散モノリス

複数のマイクロサービスをセットでデプロイしなければならず、マイクロサービス間のデプロイが独立していないような分割パターン。

例えば、マイクロサービス間で重複するロギングライブラリをマイクロサービスとして分離した結果、複数のマイクロサービスがこのロギングマイクロサービスに依存してしまうような場合がある。

分散モノリスにならないように、マイクロサービス間で使用するライブラリが重複することを許容する必要がある。


02. リポジトリ層

分割パターン

▼ ドメイン層と同じマイクロサービス

ドメイン層と同じマイクロサービス内で実行する。

最も一般的な分割パターンである。

▼ ドメイン層とは異なるマイクロサービス + 占有リポジトリ単位 (ルートエンティティ単位)

ドメイン層とは異なるマイクロサービス内で実行する。

また、占有リポジトリを単位として、マイクロサービスを分割する。

ドメイン駆動設計では、DBレコードの書き込み/読み出しのトランザクションをルートエンティティ単位で実行する。

そのため、リポジトリは実際にはルートエンティティに対応しており、ルートエンティティ単位で分割すると言い換えても良い。

▼ ドメイン層とは異なるマイクロサービス + 共有リポジトリ単位 (ルートエンティティ単位)

ドメイン層とは異なるマイクロサービス内で実行する。

また、共有リポジトリを単位として、マイクロサービスを分割する。

ただ、境界づけられたコンテキストは他のコンテキストとは異なるルートエンティティを持つため、リポジトリも完全に独立しているはずである。

そのため、異なる境界づけられたコンテキストのマイクロサービスが、同じリポジトリを共有することは起こらないはずである。

逆に言うと、複数のマイクロサービスがリポジトリを共有している場合、それらのマイクロサービスは同じコンテキストに属しており、分割する必要がないということになる。

これらのことから、この分割パターンはあまり良くない (出典は俺) 。