はじめに
レイヤード、マイクロサービス、イベント駆動...アーキテクチャスタイル(システム全体の構造パターン)の特徴は分かった。
でも、自分のプロジェクトでは結局どれを選べばいいのか?
――そんな疑問を抱えたこと、ありませんか?
この問いに対する答えは、「It depends(場合による)」です。
しかし、そこで終わりではありません。
「何に依存するのか」を体系的に整理し、判断を進めるプロセスが存在します。
この記事では、このプロセスを3つのステップに分解し、体系的に判断を進める方法を整理します。
TL;DR
- アーキテクチャの意思決定は3ステップで進める:(1) 判断基準を整理してスタイルを選ぶ、(2) パターンで設計を補完する、(3) トレードオフ分析で判断を検証する
- スタイル選定の3つの分岐点:モノリスか分散か、データをどこに置くか、同期か非同期か
- スタイルは「システム全体の構造」、パターンは「構造の中で使う設計の道具」。両者を組み合わせて初めて設計が具体化する
- 「正解のアーキテクチャ」は存在しない。あるのは 「最もマシなトレードオフの組み合わせ」 であり、文脈が変われば結論も変わる
- 3つの法則(すべてはトレードオフ、WhyはHowより重要、判断はスペクトラム上にある)が、プロセス全体の判断の質を高めるツールとして機能する
┌───────────────────────────────────────────────────────────────────┐
│ │
│ アーキテクチャ意思決定の3ステップ │
│ │
│ Step 1: 選ぶ Step 2: 補う Step 3: 検証する │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ 判断基準の整理 │ → │ パターンで │ → │ トレードオフ │ │
│ │ + 分岐点で │ │ 設計を │ │ 分析で │ │
│ │ スタイルを絞る │ │ 具体化する │ │ 判断を裏付け │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │
│ 第1法則: すべてはトレードオフ │
│ 第2法則: WhyはHowより重要 │
│ 第3法則: 判断はスペクトラム上にある │
│ │
└───────────────────────────────────────────────────────────────────┘
Step 1:選ぶ ― スタイル選定の判断基準と分岐点
なぜ「判断基準の整理」から始めるのか
アーキテクチャスタイルの「流行」は常に変化しています。
過去のアーキテクチャの反省から新しいスタイルが生まれ、DockerやKubernetesのような新技術がパラダイムそのものを変えてきました。
変化の速度自体も加速し続けており、最近の生成AIの台頭がその好例です。
流行を追うこと自体は悪くありません。
問題は、流行の「なぜ」を理解せずに採用することです。
「最近はマイクロサービスが流行っているから」という理由でスタイルを選ぶと、自分のプロジェクトの文脈と合わなかったときに痛い目に遭います。
だからこそ、自分のプロジェクトの文脈に基づいた判断基準を持つこと が出発点になります。
6つの判断基準
スタイルを選ぶ前に、以下の6つの観点から自分のプロジェクトの文脈を整理します。
| 判断基準 | 確認すること |
|---|---|
| 1. ドメイン | ビジネスドメインの主要な側面。特にスケーラビリティ・可用性など運用面への影響 |
| 2. アーキテクチャ特性 | どの特性(パフォーマンス、可用性、セキュリティなど)が必要か。スタイル間の真の違いは「各スタイルがどの特性をどれだけ支えるか」にある |
| 3. データアーキテクチャ | データベース設計、スキーマ、既存データとの統合。データ設計がアーキテクチャ設計に与える影響 |
| 4. クラウドデプロイメント | オンプレミスとクラウドのトレードオフ。データ量、データ移動コスト、弾力性の実現方法 |
| 5. 組織的要因 | クラウドベンダーのコスト、M&A(企業の合併・買収)計画、オープンソリューションへの志向など技術以外の要因 |
| 6. プロセス・チーム・運用の知識 | 開発プロセスの成熟度、チームのスキルセット、運用体制 |
特に5と6は見落としがちですが、実務ではこの「技術以外の要因」が想像以上に設計判断を左右します。
たとえば、アジャイルのエンジニアリングプラクティスが未成熟な組織でマイクロサービスを採用したとします。
スタイルが前提とするプラクティスが整っていないために苦戦しがちです。
ドメイン/アーキテクチャ同型性 という考え方も判断の助けになります。これは「問題の形がアーキテクチャの形に合っているか」を見る視点です。
たとえば、カスタマイズ性が必要なシステムなら、プラグインで機能を追加できるマイクロカーネルの形が合います。逆に、複数ページのフォームが前のページの入力内容に依存するような高度にカップリングした業務フロー(保険申請アプリなど)では、意図的にカップリングしたサービスベースアーキテクチャの形の方がフィットします。
問題の「形」を意識すると、候補が絞りやすくなります。
3つの分岐点
判断基準を整理したら、実際にスタイルを絞り込みます。
ここで考えるべき主要な分岐点が3つあります。
最初の分岐は、システム全体で1セットのアーキテクチャ特性(パフォーマンス、可用性など)で済むか、部分ごとに異なる特性が必要かという点です。
そこからデータの配置、通信方式へと判断が進みます。
分岐点1:モノリスか分散か
この分岐の鍵になるのが アーキテクチャ量子 という概念です。
アーキテクチャ量子とは、同じアーキテクチャ特性を共有するデプロイ単位のことです。
つまり、「このまとまりは一緒にデプロイされ、同じパフォーマンス要件や可用性要件を持つ」という単位です。
たとえば、1つのモノリスアプリケーションは量子が1つですが、マイクロサービスで独立デプロイする場合は量子が複数になります。
この概念を使うと、最初の問いはシンプルになります。
- 量子が1つで済む(=全体で1セットの特性で十分) → モノリスが候補
- 量子が複数必要(=部分ごとに異なる特性が必要) → 分散が候補
ただし、他の要因で分散を選ぶ場合もあります。
分岐点2:データをどこに置くか
モノリスなら単一データベースが一般的です。
分散の場合は、「どのサービスがデータを永続化するか」「データがワークフローの中をどう流れるか」を設計する必要があります。
構造(どこにデータを置くか)と振る舞い(データがどう流れるか)の両方を考えることが重要で、設計は一度で完成させるものではなく反復的に改善していきます。
分岐点3:同期か非同期か
データの配置が決まったら、サービス間の通信方式を決めます。
- 同期通信:実装やデバッグが容易で、設計上の課題が少ない
- 非同期通信:パフォーマンスやスケーラビリティで有利だが、データ同期の問題、デッドロック、レースコンディション、デバッグの難しさが伴う
原則として、デフォルトは同期、必要なときだけ非同期 です。非同期通信の恩恵が明確に必要な場合にのみ、その複雑さを受け入れます。
ケーススタディで判断プロセスを追体験する
判断基準と分岐点を整理したところで、実際のプロジェクトではどう適用するのか、2つのケーススタディで追ってみます。
ケース1:シリコンサンドイッチ(モノリスの例)
これはサンドイッチショップの注文システムのケーススタディです。
シンプルなアプリで、大きな予算もなく、アーキテクチャ特性の分析の結果、単一のアーキテクチャ量子で十分と判断されました。
- 分岐点1 → 1セットのアーキテクチャ特性で十分なので、モノリスを選択
ここから2つの設計案が検討されました。
┌─────────────────────────────────────────────────────────────────────┐
│ │
│ 案A:モジュラーモノリス │
│ ┌──────────────────────────────────────────┐ │
│ │ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────────┐ │ │
│ │ │ 注文 │ │レシピ │ │ 在庫 │ │ Override │ │ │
│ │ └──────┘ └──────┘ └──────┘ └──────────┘ │ │
│ │ 単一 DB │ │
│ └──────────────────────────────────────────┘ │
│ 特徴:ドメインごとのコンポーネント + 単一DB │
│ カスタマイズは Override コンポーネントで実現 │
│ │
│ 案B:マイクロカーネル │
│ ┌──────────────────────────────────────────┐ │
│ │ BFF(iOS) BFF(Web) BFF(Android) │ ← BFF(Backends │
│ │ ──────────────────────────────── │ for Frontends)層 │
│ │ ┌──── コアシステム ────┐ │ │
│ │ │ 注文 / レシピ / 在庫 │ │ │
│ │ └────────────────────┘ │ │
│ │ [プラグイン] [プラグイン] [プラグイン] │ ← カスタマイズ │
│ └──────────────────────────────────────────┘ │
│ 特徴:コアシステム + プラグインでカスタマイズを実現 │
│ BFFパターンでデバイス対応 │
│ │
└─────────────────────────────────────────────────────────────────────┘
どちらの案も、高パフォーマンスや弾力性が不要なため、通信は同期を採用しています。
ここで注目したいのは、同じ要件に対して複数の妥当な設計が存在する という点です。「唯一の正解」はなく、それぞれのトレードオフを比較した上で判断します。
ケース2:Going, Going, Gone(分散の例)
こちらはオンラインオークションのケーススタディです。
スケーラビリティ、弾力性、パフォーマンスに高い要求があり、競り人(オークショニア)と入札者で異なるアーキテクチャ特性が必要とされました。
- 分岐点1 → 部分ごとに異なる特性が必要なので、分散(マイクロサービス)を選択
- 分岐点2 → サービスごとにデータを保持する設計
- 分岐点3 → 同期と非同期を使い分け
非同期を選んだ箇所には明確な理由があります。
たとえば、決済(Payment)サービスは新しい決済処理に500msかかります。
大量のオークションが同時に終了したとき、同期通信だとタイムアウトや信頼性の問題が発生します。
そこでメッセージキューを介した非同期通信を採用し、信頼性を確保しています。
最終的に、アーキテクチャ特性の違いに基づいて5つのアーキテクチャ量子(決済、競り人、入札者、入札ストリーム、入札トラッカー)に分解されました。
この設計は「"正解"でも"最良"でもない」ものです。「最もマシなトレードオフの組み合わせ」です。この姿勢は、Step 3で詳しく扱うトレードオフ分析の考え方に直結します。
Step 2:補う ― パターンで設計を具体化する
スタイルを選んだだけでは設計は完成しない
Step 1でスタイルを選びましたが、「マイクロサービスにする」と決めただけでは設計は始まりません。
サービス間の通信方式は? 共通機能の再利用は? 読み書きの分離は?
こうした具体的な設計課題に答える道具が必要です。
ここからは「パターン」の話です。
まず、スタイルとパターンの違いを整理します。
- アーキテクチャスタイル:システム全体の骨格。トポロジー、デプロイ方式、通信方式、データの配置などを規定する。レイヤード、マイクロサービス、イベント駆動などがこれにあたる
- アーキテクチャパターン:骨格の中で使う設計の道具。特定の問題に対する、文脈に即した解決策。どのスタイルの中でも使える
パターンと混同されやすいものが2つあります。
「ベストプラクティス」との違い:ベストプラクティスは「常にこうすべき」という暗黙の圧力があり、思考を止めさせがちです。パターンは文脈に応じて適用するものであり、常に正解とは限りません。
「ソリューション(ツール・フレームワーク)」との違い:ツールやフレームワークはパターンを実装したものです。まず「どのパターンが適切か」を特定し、次にそのパターンを実装する最適なツールを選ぶ、という順序が大切です。
ここでは、代表的な3つのカテゴリのパターンを紹介します。
再利用パターン ― ドメインと運用の関心を分離する
分散アーキテクチャでは、各サービスのドメインロジック(そのサービス固有のビジネスロジック)は独立させたい。
一方で、監視・ログ・認証などの運用機能は全サービスで統一したいという要求もあります。
この「ドメインの独立性」と「運用の統一性」の両立が、再利用パターンの課題です。
代表的なパターンを2つ紹介します。
まず「ドメインと運用の分離」の考え方を確認し、次にその考え方を分散環境で実現するパターンを見ていきます。
ヘキサゴナルアーキテクチャ(ポート&アダプタ)
ドメインロジックを中心に置き、外部(データベース、UI、外部サービスなど)をポートとアダプタで接続する設計です。
別名「ポート&アダプタパターン」と呼ばれ、こちらの名前の方が実態を表しています。
(「ヘキサゴナル」という名前は、六角形で図を描いたことに由来するだけで、6辺に意味はありません。)
サービスメッシュ
ヘキサゴナルの「ドメインと運用を分離する」という考え方を、現代の分散アーキテクチャで実現するパターンです。
仕組みとしては、各サービスにサイドカー(サービスに横付けされる補助プロセス)を配置します。
監視・ログ・認証・サーキットブレーカー(障害の連鎖を防ぐ仕組み)などの運用機能をドメインサービスから分離します。
| 利点 | 欠点 |
|---|---|
| 運用機能を一貫した方法で分離できる | プラットフォームごとにサイドカーの実装が必要 |
| 集中管理が可能 | サイドカー自体が複雑化する可能性 |
| チーム単位・集中管理・混合の柔軟な所有権 | チーム間で実装のドリフト(ズレ)が発生しうる |
2024年にIstio Ambient MeshがGA(General Availability)に到達し、eBPFベースのCiliumなどサイドカーレスアプローチが実用段階に入っています。サイドカーの複雑さというトレードオフが大きく軽減されつつありますが、ドメインと運用を分離するという本質的なパターンは変わりません。
ヘキサゴナルもサービスメッシュも、「ドメインと運用の分離」という 同じパターンの異なる実装 です。
大事なのは、まずパターン(何を分離すべきか)を特定し、次に実装(どう分離するか)を選ぶことです。
元々のヘキサゴナルパターンは、データベースをUIと同様にアプリケーションの外部として扱い、アダプタで差し替え可能にする設計でした。つまりデータベースはサービスの「外」にある前提です。これはマイクロサービスの設計原則(データはサービスの一部である)と方向性が異なります。現在では「ドメインと運用の関心分離」という意味で使われることが多いのですが、文脈によって混乱を招くことがあります。
通信パターン ― サービス間のワークフローとデータアクセスをどう組むか
分散アーキテクチャでは、複数のサービスが協調してワークフローを実現します。
そのとき「誰がワークフロー全体を管理するのか」という問いが生じます。
これに対する2つのアプローチを見ていきます。
オーケストレーション vs コレオグラフィ
指揮者型(オーケストレーション)
専用のオーケストレータ(ワークフロー管理の専用サービス)がワークフロー全体を管理するアプローチです。
┌─────────────────────────────────────────────┐
│ 指揮者型(オーケストレーション) │
│ │
│ ┌──────────────┐ │
│ │ オーケストレータ│ │
│ └──┬──┬──┬─────┘ │
│ │ │ │ │
│ ┌─────┘ │ └─────┐ │
│ ▼ ▼ ▼ │
│ ┌──────┐ ┌──────┐ ┌──────┐ │
│ │ A │ │ B │ │ C │ │
│ └──────┘ └──────┘ └──────┘ │
│ │
│ 中央の管理者がワークフロー全体を制御する │
└─────────────────────────────────────────────┘
- 利点:ワークフローの一元管理、エラーハンドリングのしやすさ、障害時のリトライなどリカバリの容易さ、ワークフロー状態の問い合わせ
- 欠点:オーケストレータがボトルネックになり応答性が下がるリスク、単一障害点になるリスク、スケーラビリティの制約、オーケストレータとドメインサービスの結合度の高さ
自律連携型(コレオグラフィ)
各サービスが自律的に連携し、中央の管理者は存在しないアプローチです。
┌─────────────────────────────────────────────┐
│ 自律連携型(コレオグラフィ) │
│ │
│ ┌──────┐ ┌──────┐ ┌──────┐ │
│ │ A │ ──→│ B │──→ │ C │ │
│ └──────┘ └──────┘ └──────┘ │
│ ↑ │ │
│ └────────────────────────┘ │
│ │
│ 各サービスが自律的にイベントを送受信する │
└─────────────────────────────────────────────┘
- 利点:ボトルネックが少なく応答性が高い、独立したスケーリングが可能、耐障害性に優れる、サービス間の疎結合
- 欠点:ワークフロー全体の管理が困難、状態管理の困難さ、エラーハンドリングの複雑化、障害からのリカバリが難しい
この2つは、利点と欠点がきれいに裏返しの関係になっています。どちらかが「ベスト」というものではなく、ワークフローごとに適切な方式を選ぶ必要があります。
通信パターンにはもう1つの側面があります。
ワークフローの管理方式(誰が制御するか)に加えて、データアクセスの方式(読み書きをどう分けるか)も設計上の重要な判断です。
CQRS(読み書き分離)
データアクセスに関する通信パターンとしてCQRS(Command-Query-Responsibility-Segregation)があります。
一般的なクライアント/サーバー型のデータアクセスでは、読み取りと書き込みが同じデータストアに対して行われます。
しかし、読み取りと書き込みの量が大きく異なるシステムや、セキュリティ上の理由で分離したいシステムでは、これを分けるパターンが有効です。
一般的なパターン CQRS
┌──────────┐ ┌──────────┐
│ アプリ │ │ アプリ │
└────┬─────┘ └──┬───┬───┘
│ 読み書き両方 │ │
▼ 書込│ │読取
┌──────────┐ ┌──┴┐ ┌┴──┐
│ DB │ │ DB│→│ DB│
└──────────┘ │(W)│ │(R)│
└───┘ └───┘
非同期で同期
書き込み専用のデータストアと読み取り専用のデータストアを分け、書き込みストアから読み取りストアへの同期は通常非同期で行います。
これにより、読み取りと書き込みで異なるアーキテクチャ特性(スケーラビリティ、セキュリティなど)を個別に最適化できます。
インフラパターン ― イベント基盤の配置をどう決めるか
イベント駆動アーキテクチャ(サービス間の通信にイベントを使うスタイル)では、ブローカー(メッセージキューやトピックを管理する基盤)を使います。
そのブローカーを「1つに集約するか、ドメインごとに分けるか」も、パターンとして整理できます。
単一ブローカーパターン
すべてのサービスが1つのブローカーを共有します。
- 利点:どのキュー/トピックがどこにあるかが一目瞭然(一元的なディスカバリ)、インフラが最小限で済む
- 欠点:ブローカーが停止するとワークフロー全体が止まる(単一障害点)、メッセージ量が増えるとスループットの限界に達する
ドメインブローカーパターン
関連するサービス群ごとにブローカーを分けます。
- 利点:障害が特定のドメインに限定される、ドメイン境界との一致、スケーラビリティに優れる
- 欠点:キュー/トピックの発見が難しくなる、インフラのコストが増える、保守対象が増える
どちらを選ぶかは、ディスカバリの容易さとドメイン分離の必要性のバランスで判断します。ここでも「ベスト」は存在せず、文脈に応じたトレードオフです。
Step 3:検証する ― トレードオフ分析で判断を裏付ける
なぜ「選んだ後」に検証が必要なのか
Step 1でスタイルを選び、Step 2でパターンを組み合わせました。しかし、その判断は本当に妥当でしょうか。感覚ではなく体系的に検証する方法があります。
アーキテクトの仕事の本質は「銀の弾丸を見つけること」ではなく「トレードオフを分析すること」です。
ここからは、ソフトウェアアーキテクチャの3つの法則を 検証のための実践的なツール として使っていきます。
- (1) すべてはトレードオフ
- (2) WhyはHowより重要
- (3) 判断はスペクトラム上にある
それぞれを検証ツールとしてどう使うかを見ていきます。
第1法則を使う:トレードオフ分析の実践
第1法則は「ソフトウェアアーキテクチャにおいて、すべてはトレードオフである」という原則です。
ここでは、トレードオフ分析の基本と具体例、重み付けの罠、そして分析を繰り返す重要性を順に扱います。
トレードオフ分析とは、判断に影響する要素を洗い出し、各選択肢がそれぞれの要素でどう評価されるかを比較する手法です。具体例で見てみます。
具体例1:共有ライブラリ vs 共有サービス
分散アーキテクチャで共通機能を共有する方法として、「ライブラリとしてビルド時にコンパイルする」方法と「サービスとしてランタイムに呼び出す」方法があります。
まず、判断に影響する要素を洗い出します。
| 判断要素 | 共有ライブラリ | 共有サービス |
|---|---|---|
| コードの異種性(複数プラットフォーム対応) | - | + |
| コードの変更頻度 | - | + |
| バージョン管理の容易さ | + | - |
| 変更リスク | + | - |
| パフォーマンス | + | - |
| 耐障害性 | + | - |
| スケーラビリティ | + | - |
「+」の数だけ見ると、共有ライブラリの方が圧倒的に有利に見えます。
しかし、ここで安易に結論を出すと落とし穴にはまります。
この表には「すべての判断要素が同じ重みである」という暗黙の前提があるからです。
具体例2:キュー vs トピック
もう1つ、メッセージングの例を見てみます。
あるサービスがトレード情報を通知サービスと分析サービスに送りたいとします。
キュー(ポイントツーポイント通信)とトピック(ブロードキャスト通信)のどちらを使うか、という判断です。
| 観点 | キュー | トピック |
|---|---|---|
| 結合度 | 高い(送信先を知る必要がある) | 低い(送信者は受信者を知らない) |
| メッセージの柔軟性 | 消費者ごとに異なるメッセージを送れる | 全消費者が同じメッセージを受け取る |
| セキュリティ | 高い(限定された受信者) | 低い(全購読者が全内容を読める) |
| 拡張性 | 低い(消費者追加のたびに送信側も変更) | 高い(新しい消費者が自由に購読可能) |
| 個別監視・スケーリング | 可能 | 困難 |
分析が終わったら、組織の目標に立ち返ってどちらがフィットするかを判断します。セキュリティ重視ならキュー、拡張性重視ならトピック、というように。
重み付けの罠:Out of Contextアンチパターン
先ほどの共有ライブラリ vs 共有サービスの比較に立ち返ります。
単純な「+/-」の数だけで判断すると、ライブラリが勝ちます。
しかし、すべての判断要素が同じ重みとは限りません。
これを見落とすのが Out of Contextアンチパターン です。トレードオフは理解しているが、文脈に基づいた重み付けができていない状態を指します。
たとえば、複数プラットフォームのコードを扱っていて、パフォーマンスやスケーラビリティはそれほど重要でないチームの場合を考えてみます。
この文脈では、上位2つの要素(異種性・変更頻度)の重みが圧倒的に高くなります。
結果として、「+」の数では負けている共有サービスを選ぶべきという判断になります。
汎用的なトレードオフ分析はあまり役に立ちません。特定の文脈に適用して初めて価値が出る ということです。
トレードオフ分析の落とし穴
トレードオフ分析を実践する上で、もう2つ気をつけたいポイントがあります。
隠れたトレードオフ
第1法則には「トレードオフがないと思ったら、まだ見つけていないだけ」という系(補足原則)があります。
分かりやすい例が、コードの再利用です。一見すると純粋に有益に見えます。再利用できるコードが多いほど、書くコードが減って効率的になるはずです。
しかし、再利用が有効に機能するには2つの条件があります。
- 良い抽象化 ができていること
- 変更頻度が低い こと
変更頻度の高いドメインコードを無理に再利用すると、変更のたびにシステム全体に波及します。
これは、コード再利用を哲学の中心に据えていた過去のSOA(サービス指向アーキテクチャ)が教えてくれた教訓です。
最も再利用に適しているのは技術基盤(フレームワーク、ライブラリなど)であり、逆にドメインの概念は再利用の候補としては最も不向きです。
分析は一度で終わらない
第1法則にはもう1つ、「分析は一度やれば終わりではない」という系もあります。
判断に影響する変数は数十から数百に及びます。
- 技術的要因(パフォーマンス、スケーラビリティなど)
- 組織的要因(チームの経験、予算、チーム構成、スケジュールなど)
これらの変数のわずかな違いが結論を変える可能性があります。
一度の分析で恒久的な判断を下すのは危険です。
アーキテクトの仕事は「一度きりの完璧な判断」ではなく、「繰り返しのトレードオフ分析」 です。
正直なところ、これは「アーキテクトの仕事がなくならない理由」でもあります。
第2法則を使う:「なぜ」を記録する
第2法則は「なぜは、どうやってより重要である」という原則です。
トレードオフ分析の過程では、大量の文脈情報が生まれます。
どんな選択肢を比較したか、なぜこの重み付けにしたか、どんな制約があったか。
しかし、最終的な判断結果(「共有サービスを採用する」)には、そうした文脈は現れません。
「どう作ったか(How)」は既存のシステムやアーキテクチャ図を見れば分かります。しかし、「なぜこの選択をしたか(Why)」は記録しなければ失われます。
そこで重要になるのが アーキテクチャ図 と ADR です。
ADR(Architecture Decision Records:アーキテクチャ判断記録)を使って、HowとWhyの両方を残します。
これは未来の自分(または後任のアーキテクト)が判断を再検討する際の出発点になります。
ADRは軽量なフォーマットで、以下の5項目を記録します。
ADR-001: サービス間通信に非同期メッセージングを採用する
──────────────────────────────────────────────────────
ステータス: 承認済み
コンテキスト:
決済サービスは処理に500msかかり、オークション終了時に
大量のリクエストが集中する。同期通信ではタイムアウトが発生する。
決定:
決済サービスへの通信にメッセージキューを介した非同期通信を採用する。
結果:
+ 大量同時終了時の信頼性が向上する
- メッセージの順序保証やデッドレター処理の設計が必要になる
- デバッグが同期通信より困難になる
このように「なぜその判断をしたか」を文脈・決定・結果のセットで残しておくと、後から判断を再検討する際に「当時の前提が今も有効か」を確認できます。
あるソフトウェアアーキテクトは、トレーニングでアーキテクチャ演習の回答集を作ろうとしましたが、すぐに断念したそうです。参加者が描いたアーキテクチャ図(How)だけを集めても、そこには「なぜそう設計したか」という情報が欠落していたからです。Howだけでは半分のストーリーしか残らない、という好例です。
第3法則を使う:二者択一ではなくスペクトラムで考える
第3法則は「ほとんどのアーキテクチャ判断は二者択一ではなく、両極端の間のスペクトラム上に存在する」という原則です。
アーキテクチャの重要な概念に明確な境界線を引くのが難しいと感じたことはありませんか?
「アーキテクチャ vs 設計」「同期 vs 非同期」「キュー vs トピック」...。
これらに明確な線が引きにくいのは、それらが二者択一ではなく、スペクトラム(連続的な段階)上にあるからです。
たとえば、Step 2で紹介したオーケストレーションとコレオグラフィを思い出してください。
システム全体で片方だけを選ぶ必要はありません。
- 手順が決まっているワークフロー(注文処理など)はオーケストレーション寄りで管理する
- 独立性が高い処理(通知など)はコレオグラフィ寄りで各サービスに任せる
こうした使い分けがありえます。
完全 完全
オーケストレーション コレオグラフィ
◄──────────┼──────────────────┼──────────────────┼──────────►
│ │ │
注文処理 在庫更新 通知
(手順が厳密) (一部自律的に連携) (独立性が高い)
「オーケストレーションか、コレオグラフィか」ではなく、ワークフローごとにスペクトラム上のどこに位置づけるか を考える。
そうすることで、より柔軟な設計にたどり着けます。
同様に、Step 1の「モノリスか分散か」も二者択一ではありません。
モジュラーモノリスから始めて、特定のドメインだけをマイクロサービスに切り出す、というスペクトラム上の中間地点も選択肢に入ります。
「すべての答えは"場合による(It depends)"」と言われる理由は、ここにあります。
選択肢がスペクトラム上のどこに位置するかは、文脈によって変わるからです。
この視点があれば、「AかBか」という不毛な議論から、「今回の文脈ではスペクトラム上のどのあたりが適切か」 という建設的な議論に変えられます。
判断を検証する際に「この判断はAかBかの二択で捉えていないか? 中間の選択肢を検討したか?」と問い直すことで、見落としていた選択肢に気づけます。
まとめ
この記事では、アーキテクチャの意思決定を3つのステップで整理しました。
- Step 1(選ぶ):6つの判断基準でプロジェクトの文脈を整理し、3つの分岐点(モノリスか分散か、データの配置、通信方式)でスタイルの候補を絞り込む
- Step 2(補う):スタイルだけでは解決できない具体的な設計課題を、再利用・通信・インフラのパターンで補完する
- Step 3(検証する):トレードオフ分析で判断を裏付け、文脈に即した重み付けを行う。判断の「なぜ」を記録し、二者択一ではなくスペクトラムで選択肢を捉え直す
そして3つの法則(すべてはトレードオフ / WhyはHowより重要 / 判断はスペクトラム上にある)が、プロセス全体で判断の精度を上げるツールになります。
アーキテクチャに「正解」はなく、あるのはトレードオフだけです。
しかし、この3ステップのプロセスを使えば、少なくとも「なぜこの判断をしたか」を説明できる設計にはたどり着けます。
判断力は知識だけでなく実践で磨かれるものです。ぜひ自分のプロジェクトで、この3ステップを試してみてください。