Chuyển đến nội dung chính

レッスン 4: マイクロサービスの設計原則 — SRP、DDD、および境界付きコンテキスト

マイクロサービスとは何か、単一責任の原則、ドメイン駆動設計、サービス境界を定義する境界コンテキスト、疎結合と高結合度、マイクロサービスを使用すべき場合と使用すべきでない場合。

🏗️ アーキテクチャ — レッスン 4 レッスン 4: マイクロサービスの設計原則 — SRP、DDD、および境界付きコンテキスト

クラウドネイティブのマイクロサービスアーキテクチャ

パート 2: マイクロサービスの設計と通信パターン

xdev.asia

レッスン 4: マイクロサービスの設計原則 — SRP、DDD、および境界付きコンテキスト

はじめに

マイクロサービスは単に「モノリスを分割する」だけではありません。間違った方法で分割すると、両方のアーキテクチャのすべての欠点を伴う「分散モノリス」が作成されます。この記事では、マイクロサービスを適切に分割するための設計原則について説明します。


1. マイクロサービスとは何ですか?

マイクロサービスは、アプリケーションが多数の小さな独立したサービスで構成される アーキテクチャ スタイルです。

Monolith                          Microservices
┌──────────────────────┐         ┌──────────┐ ┌──────────┐
│     Một ứng dụng     │         │  Order   │ │ Payment  │
│   ┌──────┐ ┌──────┐  │         │  Service │ │ Service  │
│   │Order │ │Payment│  │   →    └──────────┘ └──────────┘
│   ├──────┤ ├──────┤  │         ┌──────────┐ ┌──────────┐
│   │Invent│ │Notif  │  │         │Inventory │ │  Notif   │
│   └──────┘ └──────┘  │         │  Service │ │ Service  │
│    Shared Database    │         └──────────┘ └──────────┘
└──────────────────────┘          Mỗi service có DB riêng

機能

  • 別のプロセスで実行: 各サービスは独立したプロセス/コンテナです
  • ネットワーク通信: HTTP/REST、gRPC、メッセージキュー
  • 独立した展開: サービス B に影響を与えずにサービス A を展開します。
  • プライベート データベース: サービスごとのデータベース パターン
  • 小規模チーム: 1 ~ 3 つのサービスを所有する 2 つのピザ チーム (5 ~ 8 人)

2. 単一責任原則 (SRP)

各サービスは 1 つの操作のみを担当し、変更する理由は 1 つあります。

✅ Đúng — Mỗi service một nghiệp vụ rõ ràng:
├── OrderService         → Quản lý vòng đời đơn hàng
├── PaymentService       → Xử lý thanh toán
├── InventoryService     → Quản lý tồn kho
├── NotificationService  → Gửi email/SMS/push
└── UserService          → Quản lý tài khoản

❌ Sai — Service "thùng rác":
├── OrderPaymentService      → 2 nghiệp vụ gộp
├── CommonService            → Mọi thứ chung
└── UtilityService           → Không rõ trách nhiệm

SRP違反の兆候

  • サービスに 無関係な API エンドポイントが多すぎます
  • 機能 A を変更するには、機能 B を再テストする必要があります
  • 多くのチームが同じサービスを修正する
  • サービス名に「and」または「util」または「common」が含まれる

3. ドメイン駆動設計 (DDD)

3.1 なぜ DDD が必要なのでしょうか?

DDD は、「各サービスの境界はどこですか?」 という最も重要な質問に答えるのに役立ちます。

DDD では、技術 (フロントエンド サービス、バックエンド サービス、データベース サービス) ごとに分割するのではなく、ビジネス ドメイン ごとに分割します。

3.2 戦略的設計

ユビキタス言語

開発者とドメイン専門家の間で 共通言語を構築します。

Domain Expert (Business):        Developer (Tech):
"Đơn hàng"                   →   Order
"Thanh toán"                  →   Payment
"Giao hàng"                  →   Shipment
"Hoàn tiền"                  →   Refund
"Kho hàng"                   →   Inventory

Đảm bảo: Code, API, database, documentation đều dùng cùng thuật ngữ

境界付きコンテキスト

境界コンテキストは、モデルが意味を持つ範囲を定義します。

┌──────────────────────────────────────────────────────┐
│                   E-Commerce System                   │
│                                                       │
│  ┌─────────────┐  ┌─────────────┐  ┌──────────────┐ │
│  │   Order      │  │  Catalog    │  │  Customer    │ │
│  │   Context    │  │  Context    │  │  Context     │ │
│  │              │  │             │  │              │ │
│  │  "Product"   │  │  "Product"  │  │  "Customer"  │ │
│  │  = OrderItem │  │  = SKU with │  │  = Account   │ │
│  │  (id, qty,   │  │  specs,     │  │  with prefs, │ │
│  │   price)     │  │  images,    │  │  addresses   │ │
│  │              │  │  pricing    │  │              │ │
│  └─────────────┘  └─────────────┘  └──────────────┘ │
│                                                       │
│  Cùng từ "Product" nhưng ý nghĩa KHÁC NHAU           │
│  trong mỗi Bounded Context                           │
└──────────────────────────────────────────────────────┘

重要なルール: 境界付けられた各コンテキスト → 1 つ (または複数) のマイクロサービス。

3.3 コンテキストのマッピング — コンテキスト間の関係

┌─────────────┐    Published    ┌──────────────┐
│   Order     │────Language────▶│   Payment    │
│   Context   │                 │   Context    │
└──────┬──────┘                 └──────────────┘
       │
       │ Customer/Supplier
       ▼
┌─────────────┐    Conformist   ┌──────────────┐
│  Shipping   │◀───────────────│  3rd Party   │
│  Context    │                 │  Logistics   │
└─────────────┘                 └──────────────┘
関係説明
共有カーネル2 つのコンテキストがサブセット コード/モデルを共有する
顧客/サプライヤー上流は API を提供し、下流は消費します。
適合者ダウンストリームはアップストリーム モデルに完全に準拠
腐敗防止層外部モデルと内部モデルの間の変換層
公開言語標準形式 (JSON スキーマ、Protobuf) で通信する

3.4 戦術的設計 — 構成要素

Bounded Context
│
├── Entity        → Có identity, lifecycle (Order, User)
├── Value Object  → Không có identity, immutable (Money, Address)
├── Aggregate     → Cluster of entities, consistency boundary
│   └── Aggregate Root → Entry point (Order là root, OrderItem là child)
├── Domain Event  → Sự kiện nghiệp vụ (OrderCreated, PaymentReceived)
├── Repository    → Persistence abstraction
└── Domain Service → Logic không thuộc entity nào (PricingCalculator)

集計 — 一貫性ユニット

Order Aggregate:
┌───────────────────────────────┐
│  Order (Aggregate Root)       │
│  ├── id: "O-001"             │
│  ├── status: "confirmed"     │
│  ├── total: $500             │
│  │                           │
│  ├── OrderItem               │
│  │   ├── product: "iPhone"   │
│  │   ├── qty: 1              │
│  │   └── price: $400         │
│  │                           │
│  ├── OrderItem               │
│  │   ├── product: "Case"     │
│  │   ├── qty: 1              │
│  │   └── price: $100         │
│  │                           │
│  └── ShippingAddress         │
│      └── "123 ABC Street"   │
└───────────────────────────────┘

Quy tắc:
- Chỉ truy cập thông qua Aggregate Root (Order)
- Một transaction = một aggregate
- Cross-aggregate = eventual consistency

4. 疎結合と高い凝集性

4.1 疎結合

サービス A を変更しても、サービス B を変更する必要はありません**。

✅ Loose Coupling:
Order Service ──event──▶ Kafka ──▶ Payment Service
(Thay đổi internal logic của Order → Payment không bị ảnh hưởng)

❌ Tight Coupling:
Order Service ──direct DB query──▶ Payment Database
(Thay đổi schema Payment DB → Order Service bị broken)

4.2 高い凝集性

関連機能は1つのサービスにグループ化されています。

✅ High Cohesion:
Payment Service:
├── ProcessPayment()
├── RefundPayment()
├── ValidateCard()
└── GetPaymentHistory()
→ Tất cả đều liên quan đến "thanh toán"

❌ Low Cohesion:
MiscService:
├── ProcessPayment()
├── SendEmail()
├── GenerateReport()
└── ResizeImage()
→ Không liên quan gì đến nhau

5. マイクロサービスを使用すべき/使用すべきでないのはどのような場合ですか?

5.1 は次の場合に使用する必要があります。

  • ✅ 大規模 システム、多くのチームが並行して開発
  • ✅ システムの各部分を個別に拡張する必要がある
  • ✅ 多言語対応 (複数の言語/フレームワーク) が必要です
  • ✅ 迅速なリリース サイクル、継続的な展開
  • ✅ 明確な境界を持つ複雑なドメイン
  • ✅ 組織は DevOps の成熟度 (CI/CD、モニタリング、コンテナ オーケストレーション) を備えています

5.2 次の場合は使用しないでください。

  • ❌ チーム 小規模 (< 5 人)
  • ❌ シンプル アプリケーション、それほど複雑ではないドメイン
  • ❌ 明確に理解されていない ドメイン境界
  • ❌ CI/CD インフラストラクチャとコンテナ オーケストレーションなし
  • ❌ 開発期間は限られています
  • ❌ チームには分散システムの運用経験がない

5.3 Monolith First

Martin Fowler は 「モノリス ファースト」 を推奨しています。

Phase 1: Monolith
├── Hiểu rõ domain
├── Phát triển nhanh
└── Xác định boundary tự nhiên

Phase 2: Modular Monolith
├── Tách module rõ ràng trong monolith
├── Mỗi module có boundary riêng
└── Giao tiếp qua internal API

Phase 3: Microservices (khi cần)
├── Tách module thành service
├── Thêm API Gateway
└── Event-driven communication

6. アンチパターンは避けるべきです

Distributed Monolith

❌ Chia thành nhiều service nhưng:
- Deploy phải đồng thời tất cả
- Shared database
- Synchronous chain calls dài
- Tightly coupled API contracts

→ Có đầy đủ nhược điểm của cả Monolith VÀ Microservices
→ Không có ưu điểm của cái nào cả

ナノサービス (小さすぎる)

❌ Chia quá nhỏ:
├── CreateOrderService
├── UpdateOrderService
├── DeleteOrderService
├── GetOrderService
└── ListOrderService

→ Quá nhiều service, overhead network, khó quản lý
→ Nên gom thành: OrderService

7. まとめ

原則キーポイント
希望小売価格各サービスにはビジネスがあり、変更する理由があります。
DD技術ではなく境界コンテキストに従ってサービスを分割する
集計整合性ユニット、集約ルート経由でアクセス可能
疎結合サービス A を変更してもサービス B には影響しません。
高い凝集力関連する機能を 1 つのサービスにグループ化
モノリスファーストモノリスから始めて、ドメインを理解したら徐々に分離

次の記事: 同期通信 — REST API と gRPC、マイクロサービス間の同期通信で最も一般的な 2 つのプロトコル。