サイトアイコンmaita tomoya dev io

アーキテクチャパターン比較

comparison

アーキテクチャパターン比較(モノリス vs マイクロサービス vs サーバーレス vs イベント駆動)

はじめに

ソフトウェアアーキテクチャの選択は、システムの開発速度・スケーラビリティ・運用コスト・チーム構成に大きな影響を与える。本ページでは、現代のソフトウェア開発で採用される4つの主要なアーキテクチャパターン — モノリスマイクロサービスサーバーレスイベント駆動 — を比較する。

各パターンの歴史的背景

パターン登場/普及時期背景
モノリス〜2000年代ソフトウェア開発の基本形。単一のデプロイ単位
SOA2000年代エンタープライズ統合。ESB(Enterprise Service Bus)中心
マイクロサービス2014年〜Martin Fowler & James Lewisが定義。Netflix, Amazonの実践から普及
サーバーレス2014年〜AWS Lambda登場。インフラ管理からの解放
イベント駆動2010年代〜Apache Kafka登場(2011)。リアルタイムデータ処理の需要拡大

各パターンの全体像

graph TB subgraph モノリス M1[単一アプリケーション] M1 --> M_UI[UI] M1 --> M_BL[ビジネスロジック] M1 --> M_DA[データアクセス] M1 --> M_DB[(単一DB)] end subgraph マイクロサービス GW[API Gateway] GW --> MS1[ユーザーサービス] GW --> MS2[注文サービス] GW --> MS3[決済サービス] MS1 --> DB1[(User DB)] MS2 --> DB2[(Order DB)] MS3 --> DB3[(Payment DB)] end subgraph サーバーレス API[API Gateway] API --> L1[Lambda: getUser] API --> L2[Lambda: createOrder] API --> L3[Lambda: processPayment] L1 --> SDB[(DynamoDB)] L2 --> SDB L3 --> SDB end subgraph イベント駆動 P[Producer] --> EB[Event Bus<br/>Kafka / EventBridge] EB --> C1[Consumer 1] EB --> C2[Consumer 2] EB --> C3[Consumer 3] end

モノリスアーキテクチャ

概要

すべての機能が単一のアプリケーションとして構築・デプロイされるパターン。最もシンプルで理解しやすい構造。

my-app/
├── src/
│   ├── controllers/    # リクエスト処理
│   ├── services/       # ビジネスロジック
│   ├── models/         # データモデル
│   ├── repositories/   # データアクセス
│   └── utils/          # ユーティリティ
├── tests/
└── package.json

メリット

メリット説明
シンプルコードベースが一つ。理解・デバッグが容易
開発速度が速い初期段階ではサービス分割のオーバーヘッドがない
テストが容易統合テストがシンプル。E2Eテストも書きやすい
デプロイが簡単1つのアーティファクトをデプロイするだけ
トランザクション管理単一DBのACIDトランザクションが使える

デメリット

デメリット説明
スケーリングの制約全体を一括でスケールする必要がある
デプロイリスク小さな変更でも全体をデプロイ。影響範囲が大きい
技術的負債の蓄積コードベースが巨大化し、変更が困難になりやすい
チーム間の競合複数チームが同一コードベースで作業すると衝突が増加
技術スタックの固定言語・フレームワークを変更しにくい

モジュラーモノリス

モノリスの利点を活かしつつ、内部をモジュール化する中間的アプローチ。

my-app/
├── modules/
│   ├── users/          # ユーザーモジュール
│   │   ├── controller.ts
│   │   ├── service.ts
│   │   └── repository.ts
│   ├── orders/         # 注文モジュール
│   └── payments/       # 決済モジュール
├── shared/             # 共有コード
└── package.json

モジュール間の依存関係を明確に管理し、将来的なマイクロサービス化への移行を容易にする。

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

概要

システムを小さな独立したサービスに分割し、それぞれが独自のデータベースを持ち、APIを通じて通信するパターン。

メリット

メリット説明
独立したデプロイ各サービスを個別にデプロイ。影響範囲が限定的
技術の多様性サービスごとに最適な言語・DBを選択可能
スケーラビリティ負荷の高いサービスだけを個別にスケール
チーム自律性小規模チームがサービスを所有(2 Pizza Rule)
障害分離1つのサービス障害が全体に波及しにくい(適切な設計の場合)

デメリット

デメリット説明
分散システムの複雑さネットワーク障害、レイテンシ、データ整合性の課題
運用負荷サービスごとの監視、ログ、デプロイパイプラインが必要
デバッグの困難さ分散トレーシングが必須(OpenTelemetry等)
データ整合性分散トランザクション、Sagaパターンの実装が必要
初期コストが高いインフラ、CI/CD、サービスメッシュ等の構築が必要

サービス間通信パターン

sequenceDiagram participant C as クライアント participant GW as API Gateway participant US as User Service participant OS as Order Service participant PS as Payment Service participant MQ as Message Queue Note over C,PS: 同期通信(REST/gRPC) C->>GW: POST /orders GW->>OS: createOrder() OS->>US: getUser() [gRPC] US-->>OS: User data Note over C,PS: 非同期通信(イベント) OS->>MQ: OrderCreated event MQ->>PS: OrderCreated event PS->>PS: processPayment() PS->>MQ: PaymentCompleted event MQ->>OS: PaymentCompleted event OS-->>GW: Order created GW-->>C: 201 Created

サーバーレスアーキテクチャ

概要

サーバーの管理をクラウドプロバイダーに完全に委ね、関数(Function)単位でコードを実行するパターン。使った分だけ課金される。

構成例(AWS)

API Gateway
    ├── GET /users    → Lambda (getUsers)    → DynamoDB
    ├── POST /users   → Lambda (createUser)  → DynamoDB
    ├── POST /orders  → Lambda (createOrder) → DynamoDB
    │                                           ↓
    │                                    DynamoDB Streams
    │                                           ↓
    │                                    Lambda (processOrder)
    │                                           ↓
    │                                    SES (メール送信)
    └── GET /reports  → Lambda (getReport)   → S3

メリット

メリット説明
運用不要サーバー管理、パッチ適用、スケーリングが自動
従量課金リクエストがなければ費用ゼロ
自動スケーリング0から数千同時実行まで自動的にスケール
高可用性マルチAZ対応が自動的に組み込まれる
開発集中ビジネスロジックに集中できる

デメリット

デメリット説明
コールドスタート初回起動に数百ミリ秒〜数秒のレイテンシ
実行時間制限AWS Lambda: 最大15分
ベンダーロックインAWS Lambda + DynamoDB + API Gateway等に依存
デバッグが困難ローカル開発環境の構築が複雑
コスト予測困難高トラフィック時はEC2より高額になることがある

イベント駆動アーキテクチャ

概要

システムの各コンポーネントがイベント(出来事)を発行・購読することで疎結合に連携するパターン。

イベント駆動の構成要素

要素説明
イベント発生した事実OrderPlaced, PaymentCompleted
Producerイベントを発行するコンポーネント注文サービス
Event Busイベントを仲介する基盤Kafka, EventBridge, SNS/SQS
Consumerイベントを受信して処理するコンポーネント決済サービス、通知サービス

メリット

メリット説明
疎結合Producerは Consumerを知らない。独立して開発・デプロイ可能
スケーラビリティConsumerを個別にスケール可能
リアルタイム処理イベント発生時に即座に処理
監査/履歴イベントログがそのまま監査証跡になる
拡張性新しいConsumerを追加するだけで機能拡張

デメリット

デメリット説明
デバッグの複雑さイベントフローの追跡が困難
結果整合性即座に一貫性が保証されない
イベント順序順序保証が難しい(パーティション設計が必要)
べき等性重複イベント処理への対策が必要
テストの難しさ非同期処理のテストが複雑

総合比較表

項目モノリスマイクロサービスサーバーレスイベント駆動
複雑さ
初期開発速度最速遅い速い遅い
スケーラビリティ制限あり高い非常に高い高い
運用コスト低〜中低(従量課金)中〜高
デプロイ全体一括サービス単位関数単位サービス単位
データ整合性ACID結果整合性結果整合性結果整合性
チーム規模1〜20人20人以上1〜10人10人以上
技術的自由度中(ベンダー依存)
テスト容易性低〜中
デバッグ容易性

移行パス

graph LR A[モノリス] -->|モジュール化| B[モジュラーモノリス] B -->|段階的分割| C[マイクロサービス] C -->|一部関数化| D[マイクロサービス + サーバーレス] C -->|非同期化| E[マイクロサービス + イベント駆動] A -->|小規模なら| F[サーバーレス] style A fill:#ffcccc style B fill:#ffe6cc style C fill:#ccffcc style D fill:#ccffff style E fill:#ccccff style F fill:#e6ccff

移行の原則

  1. Big Bang リライトは避ける: 段階的に移行する(Strangler Fig パターン)
  2. 境界を見極める: ドメイン駆動設計(DDD)のBounded Contextを活用
  3. データの分離から始める: 各サービスのデータベースを分離
  4. 監視基盤を先に構築: 分散トレーシング、集中ログを事前に用意
  5. チーム構成を合わせる: コンウェイの法則を意識。組織とアーキテクチャを一致させる

Strangler Fig パターン

Phase 1: モノリスの前にAPI Gatewayを配置
Phase 2: 新機能をマイクロサービスとして開発
Phase 3: 既存機能を段階的にマイクロサービスに移行
Phase 4: モノリスが不要になったら廃止

選定フローチャート

flowchart TD A[アーキテクチャを選ぶ] --> B{チーム規模は?} B -->|小規模 1-10人| C{トラフィックパターンは?} C -->|安定| D[モノリス / モジュラーモノリス] C -->|スパイク型<br/>不定期| E[サーバーレス] B -->|中〜大規模 10人以上| F{独立したデプロイが必要?} F -->|はい| G{リアルタイム<br/>データ処理が重要?} G -->|はい| H[マイクロサービス + イベント駆動] G -->|いいえ| I[マイクロサービス] F -->|いいえ| J[モジュラーモノリス]

実際のアーキテクチャ選択例

企業/サービスアーキテクチャ理由
スタートアップ初期モノリス開発速度最優先。機能を素早くリリース
Netflixマイクロサービス数百のサービスを独立したチームが運用
Amazonマイクロサービス + イベント駆動注文→在庫→配送を非同期イベントで連携
Vercel Functionsサーバーレスエッジでの関数実行。グローバル配信
ShopifyモジュラーモノリスRuby on Railsのモノリスをモジュール化して維持

まとめ

  • モノリス: 小規模チーム、MVPに最適。まずはここから始める
  • マイクロサービス: 大規模チーム、独立デプロイが必要な場合に検討
  • サーバーレス: 運用負荷を最小化したい場合、スパイク型トラフィックに最適
  • イベント駆動: リアルタイム処理、疎結合な非同期システムに最適

最も重要な原則は**「早すぎる最適化を避ける」**こと。モノリスから始め、実際のボトルネックが見えてから分割を検討するアプローチが推奨される。

参考文献