手当たり次第に書くんだ

飽きっぽいのは本能

責務を固定し、統合を固定しない――マイクロサービスを再構成可能性から捉える

マイクロサービスアーキテクチャは、一般に、アプリケーションを小さなサービスへ分割し、それぞれを独立して開発・デプロイする方式として説明されます。しかし、「小さなサービスへ分割する」という説明だけでは、なぜ分割するのか、どこに境界を置くべきなのかが十分に見えてきません。

サービス数を増やすことや、プログラムを複数のコンテナで動かすこと自体が目的ではありません。重要なのは、比較的長く維持される責務を独立したシステムとして定義し、それらの組み合わせ方を、利用目的に応じて変えられるようにすることです。本稿では、この性質を「再構成可能性」という観点から考えます。

この整理は、3 本の連続した記事として扱います。第 1 本である本記事では、ドメインサービス、利用目的別の構成層、共通プラットフォーム、分析基盤というシステム上の責務境界を定義します。第 2 本「システム境界と組織境界をどう揃えるか」では、その境界をどのチームが所有するかを扱います。第 3 本「AI エージェントの境界はどこに置くべきか」では、AI エージェントをどの境界に置き、委任、承認、監査をどう記録するかを扱います。

参考
書籍
参考書籍

実践ドメイン駆動設計

境界づけられたコンテキスト、責務、モデル、システム境界を考える際の参考書籍です。価格や在庫はリンク先で確認してください。

Amazon で見る

このリンクは Amazon アソシエイトリンクです。

一つの障害調査には複数のシステムが関係する

通信サービスの利用者から、「通信が遅い」という問い合わせがあったとします。原因を調査するには、顧客と契約内容、対象サービスと回線、回線を構成する装置とインターフェース、装置のアラーム、トラフィック、遅延、パケットロス、経路情報、構成変更履歴、過去の障害チケットなど、複数の情報が必要です。

これらを一つの運用システムへ集約することは可能です。しかし、必要な情報や調査手順は問題によって変わります。通信遅延、経路異常、装置故障、認証エラーでは、確認すべき情報も実行する操作も同じではありません。すべての用途を一つのデータモデルと画面へ組み込むと、新しいサービスや調査方法が増えるたびに、中央のシステムを変更しなければなりません。

別の方法は、顧客管理、契約管理、サービス管理、ネットワーク構成管理、監視、変更管理、チケット管理を、それぞれ独立した責務として提供することです。障害調査の画面やワークフローは、その時点の問題に必要な情報だけを組み合わせます。ここで分割するのは、単なるプログラムではありません。「どの情報と判断規則について、どのシステムが正しさに責任を持つか」という境界です。

関数やオブジェクトをシステム単位へ広げる

関数は、入力を受け取り、処理を行い、結果を返します。利用側が知る必要があるのは、どのような入力を与えれば、どのような結果が返るかという契約です。内部の処理方法まで知る必要はありません。サービスも同様に、API やイベントを受け取り、自分の責務に基づいて処理し、結果を返します。この意味では、マイクロサービスはネットワーク越しに利用する関数に似ています。

ただし、通常の関数呼び出しとは異なり、ネットワーク越しの呼び出しには、遅延、タイムアウト、通信断、再送、重複処理、部分障害があります。関数との類似は責務と契約に関するものであり、実行特性まで同じではありません。オブジェクト指向との対応も、責務と状態の所有という観点では分かりやすいものです。

オブジェクトは、自分の状態と振る舞いを持ち、外部には許可された操作だけを公開します。契約管理サービスであれば、契約データを保存するだけではありません。契約がどの条件で成立し、変更され、終了するかという規則を持ちます。他のサービスは、契約管理サービスのデータベースを直接更新せず、公開された API やイベントを通じて契約を扱います。Domain-Driven Design における Bounded Context も、モデルと言語が有効な範囲を定め、異なる文脈間の関係を明示するための考え方です。

マイクロサービスは、関数やオブジェクトで使われてきた、責務を限定する、状態と判断規則を同じ境界で管理する、内部実装を外部へ露出しない、外部との関係を契約として定義する、という原則をシステム単位へ広げたものと考えられます。重要なのはサービスの小ささではなく、責務、状態、判断規則、変更権限が同じ境界に収まっていることです。

統合の責任はどこに置かれるのか

サービスを責務ごとに分けると、顧客情報、契約情報、構成情報、監視情報も分散します。複数サービスの情報をどのようにまとめるかは、個々のサービスではなく、利用目的に近い層が担当します。ただし、統合に関わる仕組みをすべて「統合層」と一括りにすると、責務が分かりにくくなります。

区分主な責任
ドメインサービス顧客管理、契約管理、監視正式なデータ、業務ルール、API・イベント契約
利用目的別の構成層BFF、API 集約、ワークフロー、フロントエンド特定の業務や画面に必要な情報と操作を構成する
共通プラットフォームAPI Gateway、イベント基盤、認証、検索基盤複数サービスが共通して利用する技術能力を提供する
分析基盤データウェアハウス、データレイク、BI履歴を蓄積し、横断的な集計や分析を可能にする
利用者運用者、設計者、顧客担当者提示された情報を基に判断し、操作する

フロントエンド、BFF、API 集約サービス、ワークフローは、主に「利用目的別の構成層」に属します。BFF は、すべてのフロントエンドが一つの汎用バックエンドを利用するのではなく、フロントエンドごとに適したバックエンドを設けるパターンです。Microsoft の Backends for Frontends パターンでも、異なるインターフェースの要求へ個別に対応する構成として説明されています。

検索基盤は、複数の業務から共有される場合には共通プラットフォームに属します。特定の業務だけに最適化された検索インデックスであれば、利用目的別の構成層に含めることもできます。分析基盤は、リアルタイムの業務処理とは異なるデータ保持と整合性を必要とするため、独立した区分として扱う方が分かりやすいでしょう。

統合の主体が利用目的に近い側へ移ったとしても、統合可能なデータと契約を提供する責任は、各ドメインサービスに残ります。顧客 ID、契約 ID、サービス ID、回線 ID、装置 ID などが関連付けられなければ、構成層は情報を結合できません。API やイベントについても、データの意味、時刻、更新頻度、所有者、互換性が明確である必要があります。疎結合とは関係をなくすことではなく、暗黙的な依存を管理可能な契約へ変えることです。

統合層を中央モノリスにしない

個々のサービスを分割しても、すべての業務判断とサービス連携を一つの統合システムへ集めれば、新しい中央モノリスが生まれます。すべてのサービスを知る巨大な API 集約サービスや、すべての業務手順を制御する中央ワークフローは、各サービスの自律性を損なう可能性があります。

所有形態意味
利用側のチームが所有する顧客向けポータルの BFF は顧客向けサービスのチームが、運用画面の BFF やワークフローは運用業務を理解するチームが所有する。
ドメイン側が利用しやすい API を提供する複数の利用側が同じ複雑な呼び出しを繰り返すなら、ドメインサービス側が業務的な粒度の API やイベントを提供する。
プラットフォームチームが共通能力を提供する認証、API Gateway、イベント配信、サービスディスカバリー、監視、検索エンジンなどを共通サービスとして提供する。

プラットフォームチームの役割は、業務上の統合判断を中央で引き受けることではありません。各チームが自律的にサービスを提供し、組み合わせられるための技術能力を、共通サービスとして提供することです。この区別が曖昧になると、プラットフォームチームが全サービス間の調整窓口となり、組織上のボトルネックになります。

構成可能な UI は既存概念の交差点にある

バックエンドの能力とデータが分かれているなら、UI も必ずしも一つの完成されたアプリケーションである必要はありません。顧客情報、契約情報、ネットワークトポロジー、アラーム、トラフィック、変更履歴、操作機能を部品として提供し、業務の目的に応じて組み合わせることが考えられます。このような構造を、ここでは便宜的に「マイクロ UI」と呼びます。

ただし、これは既存研究に存在しなかった新しい技術方式を主張する言葉ではありません。関連する既存概念には、マイクロフロントエンド、BFF、ロールベースのポータル、Composable Architecture、Adaptive UI、Context-Aware UI などがあります。マイクロフロントエンドは、主にフロントエンドコードと開発チームを分割し、独立して変更・デプロイできるようにする考え方です。

BFF は、Web やモバイルなどの利用インターフェースに合わせて、バックエンドのデータや操作をまとめます。BFF が参照だけでなく、書き込み操作を仲介することも一般的です。Adaptive UI や Context-Aware UI は、利用者、端末、場所、作業状態などの文脈に応じて、表示や操作方法を変化させます。したがって、「書き込み操作を含むこと」や「文脈に応じて画面が変わること」だけでは、既存概念との差分にはなりません。

本稿が注目しているのは、UI 技術そのものではなく、その背後にある責任構造です。情報や操作の正式な所有者が独立したドメインサービスとして存在し、利用目的別の構成層は元サービスの責務を奪わずに情報と操作を組み合わせる。同じドメインサービス群から、異なる業務目的に適したビューやワークフローを構成できる。つまり、構成可能な UI は、新しい UI 方式というより、バックエンドの責務分割を利用者が扱う情報と操作の構成まで一貫させる考え方だと言えます。

障害調査と経営分析では統合方式が異なる

同じサービス群を利用する場合でも、用途によって適切な統合方式は変わります。通信障害の調査では、現在の状態と、障害発生時刻の前後に何が起きたかを短時間で確認する必要があります。利用者が顧客またはサービスを選択すると、構成層はサービス ID や回線 ID から対象装置を特定し、問い合わせ時刻を中心に、アラーム、トラフィック、経路、構成変更を同じ時間軸へ並べます。

サービス所有する責務調査で利用する情報
顧客・契約管理顧客、契約、SLA顧客、契約条件
サービス管理顧客サービスと回線の関係対象回線、サービス ID
ネットワーク構成管理装置、回線、接続関係経路、装置、インターフェース
監視メトリクス、アラーム遅延、パケットロス、トラフィック
構成変更管理設定内容と変更履歴変更者、時刻、設定差分
チケット管理障害対応の進行状態過去事例、対応履歴

この用途では、秒から分単位の鮮度が求められます。現在の正式な状態は元サービスの API から取得し、大量の監視データや履歴は検索インデックスや時系列データベースから参照する構成が考えられます。一部のサービスが応答しない場合でも、取得できた情報だけを表示し、欠落している情報源を明示する必要があります。

一方、経営分析では、一件の障害を即座に調べるのではなく、一定期間の傾向や事業への影響を把握します。契約の開始、変更、解約履歴、顧客とサービスの関係、障害の開始時刻、復旧時刻、原因分類、影響を受けた回線、サービス、顧客、SLA 違反時間、問い合わせ件数、対応時間、利用料金や売上区分などを分析基盤へ取り込みます。

分析基盤では、顧客 ID、契約 ID、サービス ID、障害 ID などの対応関係を保持し、履歴を時系列で蓄積します。そこから、月別の障害件数、影響顧客数、SLA 違反時間、同一原因による再発率、サービス別の問い合わせ率、障害による売上影響などを集計します。この用途では、秒単位の鮮度よりも、後から原因分類や顧客影響が訂正された場合に再集計できること、過去時点の契約や構成を再現できること、元データと照合できることが重要です。

観点障害調査経営分析
主な目的現在の問題を特定する長期的な傾向と影響を把握する
鮮度秒から分時間から日
データ粒度個別顧客、回線、装置月、サービス、顧客区分
主な統合方式API、検索、時系列照合イベント、CDC、ETL、分析用ストア
整合性欠落や遅延を明示して部分表示遅延を許容し、後から再計算する
派生データの所有者構成層が一時的なビューを作る分析基盤が履歴・集計結果を管理する

障害調査と経営分析では、同じ顧客、契約、サービス、障害という情報を扱っていても、鮮度、整合性、履歴の持ち方、派生データの所有者が異なります。一つの中央統合方式を決めるのではなく、同じ責務単位を維持しながら、利用目的に適した統合方式を選ぶことが重要です。

システムの責務と組織の責務

マイクロサービスの構造は、責務がよく定義された組織にも似ています。ただし、プログラム、システム、組織を完全に同一視することはできません。対応関係を整理すると、モジュールやオブジェクトはドメインサービスに、ドメインサービスはドメインチームに近い位置を持ちます。API やイベント契約は、チーム間の依頼条件や成果物に対応します。

プログラムシステム組織
モジュール・オブジェクトドメインサービスドメインチーム
関数呼び出し・インターフェースAPI・イベント契約チーム間の依頼条件・成果物
状態の所有サービスがドメインデータを所有するドメインチームが管理対象に責任を持つ
利用側の合成処理BFF・ワークフロー・UI 構成プロダクトチーム・業務チーム
共通ランタイム・ライブラリ認証・イベント・監視などの基盤プラットフォームチーム
内部実装の隠蔽DB 構造や処理方式を公開しない他チームが内部手順を直接規定しない

顧客向けサービスであれば、顧客、契約、課金などのドメインチームが、正式なデータと業務ルールを所有します。顧客ポータルを担当するプロダクトチームは、それらを顧客向けの体験として構成します。プラットフォームチームは、認証、イベント配信、監視、デプロイなど、両者が利用する共通能力を提供します。プラットフォームチームが業務上の統合判断まで引き受けると、すべての変更が中央チームを経由するようになります。

反対に、各プロダクトチームが認証や監視基盤まで個別に作ると、重複と不統一が発生します。どこまでをドメイン、利用目的別の構成、共通プラットフォームとして分けるかは、システム設計と組織設計の両方に関わる問題です。組織のコミュニケーション構造とシステム構造の関係は、Melvin E. Conway の 1968 年の論文 How Do Committees Invent? にまで遡ります。ただし、Conway の法則と逆 Conway マヌーバーを具体的な組織設計へどう適用するかは、第 2 本「システム境界と組織境界をどう揃えるか」で扱います。

再構成可能性にはコストがある

マイクロサービスや構成可能な UI によって、異なる用途へ対応しやすくなります。一方で、その柔軟性は無料ではありません。サービスを独立して変更するには、API やイベントの後方互換性、バージョニング、廃止手順、契約テストが必要です。Microsoft の マイクロサービス設計ガイドでも、API 契約を破壊するとクライアントや API Gateway へ影響し、サービスが独立して進化しにくくなることが指摘されています。

サービスごとにデータを所有すると、複数サービスをまたぐ変更を一つのデータベーストランザクションとして扱えない場合があります。イベントによる連携では、一時的な不整合を前提として、再送、重複排除、冪等性、補償処理、照合処理を設計する必要があります。

一つの画面を表示するために多数のサービスへ同期的に問い合わせると、遅延と障害点が増えます。タイムアウト、キャッシュ、部分表示、縮退動作を設計しなければなりません。また、呼び出しをまとめる API Gateway や集約サービス自体が、すべてのサービスを知る巨大なオーケストレーターになる可能性があります。Microsoft の API Gateway パターンに関する設計ガイドでも、単一の API Gateway へすべての内部マイクロサービスを集約すると、モノリシックな集約機能となり、各サービスの自律性を損なう危険が示されています。

顧客 ID、契約 ID、回線 ID、装置 ID などの対応関係がなければ、情報を統合できません。一方で、すべてのサービスへ単一の共通データモデルを強制すると、各ドメインの文脈が失われます。共通して扱う識別子と、各 Bounded Context の内部で独立して定義する意味を区別する必要があります。

複数サービスの情報と操作を一つの UI へ集める場合、表示権限、変更権限、承認権限を個別に評価する必要があります。利用目的別の構成層が、元サービスの認可を回避して独自に権限を判断すると、責任境界が崩れます。一方、すべての操作について複数サービスへ個別に認可を問い合わせれば、処理と監査が複雑になります。

分散したサービスを運用するには、ログ、メトリクス、トレース、デプロイ、サービスカタログ、依存関係管理などの共通基盤が必要です。サービスを分けるほど、個々の内部実装を見るだけでは全体の状態を理解できなくなります。マイクロサービスは複雑さを消すものではありません。一つのプログラム内部にあった複雑さを、サービス境界、ネットワーク、データ整合性、契約、統合基盤の管理へ移します。

常にマイクロサービスが適切とは限らない

利用目的が一つで、変更頻度が低く、一つのチームが全体を管理し、強いトランザクション整合性が必要であれば、一つのシステムとして作る方が合理的です。その場合でも、内部を責務ごとのモジュールへ分けたモジュラーモノリスとすることで、責務境界と情報隠蔽は維持できます。

ネットワーク越しに分割する価値があるのは、独立した変更、所有、運用、拡張、再利用による利益が、分散システムのコストを上回る場合です。UI についても、利用者ごとに自由な構成が必要とは限りません。業務手順を標準化すべき領域では、提供側が完成された画面と操作順序を定義した方が、教育、品質、監査の面で有利です。再構成可能性は目的ではなく、変化する利用目的へ対応するための選択肢です。

何を固定し、何を変えられるようにするのか

マイクロサービスを小さなプログラムの集合と捉えると、サービス数やコンテナ数の議論に陥りやすくなります。本来考えるべきなのは、どの業務概念について、どのサービスとチームが状態、規則、変更、品質に責任を持つかです。その責務境界が適切に定義されていれば、個々のサービスは長期間安定して存在できます。

一方、それらから作る画面、ワークフロー、検索、分析は、顧客対応、障害調査、経営分析などの目的に応じて変えられます。マイクロサービス、構成可能な UI、責務の明確な組織は、別々の問題ではありません。いずれも、何を独立した責務として安定させ、何を利用目的に応じて組み替えられるようにするか、という同じ設計問題を扱っています。システムを細かく分割することよりも、この境界を見つけることの方が重要です。

参考情報

関連する記事

関連する記事
責務を固定し、統合を固定しない――マイクロサービスを再構成可能性から捉える

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

トップへ戻る