API Composition
ある一つのサービスが中心となってデータを収集、結合を行う方式です。
デメリット
- オーバーヘッドが高くなる。
- 可用性が下がる可能性がある。
CQRS(コマンドクエリ責務分離)
データベースへの書き込みと読み込みを分ける原則です。マイクロサービスアーキテクチャで分散データベースが当たり前になってきていることから現在主流になってきている考え方になります。
主にオーバーヘッドがかかるのは複数サービスからの値の参照の必要のある読み取り側の処理になります。(書き込み側の処理は単一サービスに対して行うのでORマッパーをそのまま使えばよくそこまでオーバーヘッドはかかりません。)、なのでコマンドとクエリを分離するCQRSという考え方がマイクロサービスでは主流になっています。
背景
マイクロサービスでは様々なサービスが保持しているDBから収集、結合することが求められる。特に読み取りのさいは非常にオーバーヘッドが非常に高くなってしまいます。実装方法によってはHTTP通信が大量に発生してプログラムの実行回数が増えてしまう。
なのでCQRSを使って読み取りと書き込みを分けることを推奨している。
コマンド(書き込み)
基本的には自分たちのサービスだけの処理になるのでORマッパーをそのまま使ってしまえば良いです。
オブジェクトの状態を変更するメソッドは値を戻してはいけない。戻り値の型はvoidとする。
クエリ(読み込み)
分散されたサービスから値を取得する必要があるので一発で引けるような状態を作ってあげる必要があります。つまりあらかじめメッセージブローカーやAPI通信を使って必要なデータを取得しておきます。
メソッドが型や値を戻す場合、オブジェクトの状態を変更してはいけない。
DDDと組み合わせた際の流れ
1.コマンド処理(コマンドプロセッサ/コマンドハンドラ)
コマンド処理には3方式あります。どの方式にせよ集約のインスタンスを作成/取得し、更新用のメソッドを実行します。
分類方式(アプリケーションサービスに複数のコマンドメソッドを追加)
開発が容易です。
専用方式(単一メソッドを持つ単一クラスを作成)
コマンドごとの責務が明確になります。
メッセージング方式
非同期処理の場合に使います。「専用方式」のコマンドクラスを非同期のメッセージとして送信します。
2.コマンドモデル
通常は、集約がコマンドモデルになります。最後にイベントを発行します。
3.コマンドモデル用データストア
コマンドモデルの更新結果をレポジトリ経由で保存します。
4.クエリモデル(ビュー)を更新(イベントのサブスクライバ)
サブスクライバ(購読者)が発行したドメインイベントを受信します。受け取ったイベントに応じてクエリモデルを更新します。
5.クエリモデル用データストア
描画用のデータが格納されています。格納場所はデータベースが一般的。
6.クエリモデル(Readモデル)
画面表示や印刷用のための非正規化されたデータモデル
7.クエリ処理(クエリプロセッサ)
データベースの問い合わせ結果をJSON、XML化したり、DTOに詰め替えたりします。
同期か非同期か
機能要件次第
同期
「コマンドモデル用データストア」と「クエリモデル用データストア」を用意して同じトランザクションで処理すれば同期になる。
メリット
一貫性が保証される。
デメリット
処理に時間がかかる。
非同期
同期の逆、一貫性が保たれないので「結果整合性」を保てるようにする考え方が一般的。
この記事へのコメントはありません。