ストーリー
高橋アーキテクト が手を止めました。
サービス分割の原則
1. ドメイン駆動設計(DDD)による境界
最も効果的なアプローチは、ビジネスドメインに沿った分割です。
// ECサイトのドメイン分析例
const boundedContexts = {
// 境界づけられたコンテキスト
identity: {
entities: ["User", "Role", "Permission"],
responsibility: "認証・認可",
},
catalog: {
entities: ["Product", "Category", "Review"],
responsibility: "商品情報の管理",
},
ordering: {
entities: ["Order", "OrderItem", "OrderStatus"],
responsibility: "注文ライフサイクルの管理",
},
payment: {
entities: ["Payment", "Refund", "Invoice"],
responsibility: "決済処理",
},
shipping: {
entities: ["Shipment", "Tracking", "Carrier"],
responsibility: "配送管理",
},
};
2. チーム構造との整合(コンウェイの法則)
「システムの設計は、それを作る組織のコミュニケーション構造を反映する」 — メルヴィン・コンウェイ
組織構造:
┌─────────────┐ ┌──────────────┐ ┌────────────┐
│ ユーザーチーム │ │ 商品チーム │ │ 注文チーム │
│ 5人 │ │ 4人 │ │ 6人 │
└──────┬────────┘ └───────┬────────┘ └──────┬─────┘
│ │ │
サービス分割:
┌──────┴────────┐ ┌───────┴────────┐ ┌──────┴─────┐
│ User Service │ │ Product Service │ │ Order │
│ │ │ │ │ Service │
└────────────────┘ └─────────────────┘ └────────────┘
3. 変更頻度による分割
変更頻度分析:
┌──────────────────────────┐
│ モノリス │
│ │
│ [検索] 週5回変更 │ ← 高頻度:独立させる
│ [支払] 月1回変更 │ ← 低頻度:安定
│ [通知] 週3回変更 │ ← 中頻度
│ [認証] 年2回変更 │ ← 超低頻度:分ける価値が低い
│ │
└──────────────────────────┘
分割のアンチパターン
アンチパターン1: 技術レイヤーでの分割
BAD: 技術レイヤーで分割
┌───────────┐ ┌──────────┐ ┌───────────┐
│ UI Service │ │ Logic │ │ Data │
│ │ │ Service │ │ Service │
└────────────┘ └──────────┘ └───────────┘
→ 1つの機能変更で3サービスを変更する必要がある
GOOD: ビジネスドメインで分割
┌───────────┐ ┌──────────┐ ┌───────────┐
│ Order │ │ Payment │ │ Shipping │
│ Service │ │ Service │ │ Service │
│ [UI+Logic │ │ [UI+Logic│ │ [UI+Logic │
│ +Data] │ │ +Data] │ │ +Data] │
└───────────┘ └──────────┘ └───────────┘
→ 注文の変更はOrder Serviceのみ
アンチパターン2: 細かすぎる分割
// BAD: ナノサービス(細かすぎ)
const services = [
"email-validation-service", // メールバリデーションだけ?
"password-hashing-service", // ハッシュ化だけ?
"date-formatting-service", // 日付フォーマットだけ?
];
// GOOD: ビジネスの意味のある単位
const services = [
"identity-service", // 認証・認可をまとめて
"catalog-service", // 商品カタログを管理
"order-service", // 注文ライフサイクルを管理
];
アンチパターン3: 共有データベース
BAD: データベースを共有
┌──────────┐ ┌──────────┐
│ Service A │ │ Service B │
└─────┬─────┘ └─────┬─────┘
│ │
└──────┬───────┘
┌─────┴─────┐
│ Shared DB │ ← スキーマ変更が全サービスに影響
└───────────┘
GOOD: データベースを分離
┌──────────┐ ┌──────────┐
│ Service A │ │ Service B │
│ │ │ │
│ [DB A] │ │ [DB B] │ ← 独立して進化できる
└───────────┘ └───────────┘
分割の判断チェックリスト
interface ServiceBoundaryCheck {
// 独立性の確認
canDeployIndependently: boolean; // 他サービス変更なしにデプロイ可能?
ownsItsData: boolean; // 自分のデータを完全に所有?
hasBusinessMeaning: boolean; // ビジネス上の意味のある単位?
// 粒度の確認
notTooSmall: boolean; // ライブラリで十分ではないか?
notTooBig: boolean; // 複数の責務を持っていないか?
// チームの確認
singleTeamOwnership: boolean; // 1チームが所有できるサイズ?
clearApiContract: boolean; // API契約が明確?
}
Strangler Figパターン:段階的な移行
一度にすべてを分割するのではなく、モノリスから段階的にサービスを切り出します。
Phase 1: モノリスの前にProxyを配置
Client → [Proxy] → [Monolith]
Phase 2: 1つのドメインを切り出し
Client → [Proxy] → [Order Service](新)
→ [Monolith](残り)
Phase 3: 徐々に切り出しを進める
Client → [Proxy] → [Order Service]
→ [Payment Service](新)
→ [Monolith](さらに縮小)
まとめ
| ポイント | 内容 |
|---|---|
| 最良の基準 | DDDの境界づけられたコンテキスト |
| コンウェイの法則 | チーム構造とサービス構造を合わせる |
| 避けるべき | 技術レイヤー分割、ナノサービス、共有DB |
| 移行戦略 | Strangler Figパターンで段階的に |
チェックリスト
- DDDの境界づけられたコンテキストを説明できる
- コンウェイの法則を理解した
- 3つのアンチパターンを挙げられる
- Strangler Figパターンの概要を理解した
次のステップへ
次は分散システムが抱える課題の全体像を把握します。これにより、Step 2以降で学ぶ各解決策の位置づけが明確になります。
推定読了時間: 25分