ストーリー
ミッション概要
| ミッション | テーマ | 目安時間 |
|---|---|---|
| Mission 1 | モノリスのアンチパターン特定 | 15分 |
| Mission 2 | 技術的負債ヒートマップ作成 | 15分 |
| Mission 3 | モジュール間依存グラフの作成 | 15分 |
| Mission 4 | 移行アセスメントレポート作成 | 15分 |
前提シナリオ
あなたは大規模ECプラットフォーム「ShopMaster」のテックリードです。このシステムは5年前にRuby on Railsのモノリスとして構築され、現在以下の状況です:
- コードベース: 約50万行
- デプロイ頻度: 月2回(リリーストレイン方式)
- チーム: 8チーム40名が同一リポジトリで開発
- DB: 単一のPostgreSQLインスタンス(300テーブル以上)
- 平均ビルド時間: 45分
- テストスイート実行時間: 2時間
- 障害時の平均復旧時間(MTTR): 4時間
Mission 1: モノリスのアンチパターン特定(15分)
要件
ShopMasterのコードベースから以下のアンチパターンを特定し、影響度と改善優先度を評価してください。
graph TD
Root["ShopMaster/"] --> App["app/"]
App --> Models["models/"]
App --> Ctrl["controllers/"]
App --> Svc["services/"]
App --> Jobs["jobs/"]
Models --> M1["order.rb\n2,800行 / 35メソッド"]
Models --> M2["product.rb\n1,500行 / 22メソッド"]
Models --> M3["user.rb\n1,200行 / 18メソッド"]
Models --> M4["payment.rb\n900行 / Stripe API直接コール"]
Ctrl --> API["api/v1/"]
API --> C1["orders_controller.rb\n500行 / 在庫・決済・通知を直接呼出"]
Svc --> S1["order_service.rb\n800行 / 他サービス直接参照"]
Svc --> S2["payment_service.rb\n600行 / 循環依存あり"]
Svc --> S3["notification_service.rb\n全サービスから直接呼出"]
Jobs --> J1["order_sync_job.rb\n外部API / リトライロジック散在"]
style Root fill:#1e293b,stroke:#475569,color:#f8fafc
style App fill:#dbeafe,stroke:#2563eb,color:#1e40af
style Models fill:#f3e8ff,stroke:#7c3aed,color:#5b21b6
style Ctrl fill:#f3e8ff,stroke:#7c3aed,color:#5b21b6
style Svc fill:#f3e8ff,stroke:#7c3aed,color:#5b21b6
style Jobs fill:#f3e8ff,stroke:#7c3aed,color:#5b21b6
style API fill:#f3f4f6,stroke:#9ca3af,color:#374151
style M1 fill:#fee2e2,stroke:#dc2626,color:#991b1b
style M2 fill:#fef3c7,stroke:#d97706,color:#92400e
style M3 fill:#d1fae5,stroke:#059669,color:#065f46
style M4 fill:#fee2e2,stroke:#dc2626,color:#991b1b
style C1 fill:#fee2e2,stroke:#dc2626,color:#991b1b
style S1 fill:#fee2e2,stroke:#dc2626,color:#991b1b
style S2 fill:#fee2e2,stroke:#dc2626,color:#991b1b
style S3 fill:#fef3c7,stroke:#d97706,color:#92400e
style J1 fill:#fef3c7,stroke:#d97706,color:#92400e
解答例
| アンチパターン | 箇所 | 影響度 | 優先度 |
|---|---|---|---|
| God Object | order.rb(2,800行) | 高 | 1 |
| 循環依存 | order_service ↔ payment_service | 高 | 1 |
| 密結合 | orders_controller が在庫・決済・通知を直接呼出 | 高 | 2 |
| Shared DB依存 | 300テーブルが単一DBに集中 | 高 | 2 |
| 横断的関心事の散在 | notification_serviceが全箇所から直接呼出 | 中 | 3 |
| インフラ依存混入 | payment.rbにStripe APIコールが直接記述 | 中 | 3 |
| リトライロジック散在 | order_sync_jobにリトライが直書き | 低 | 4 |
影響分析:
- God Object(order.rb): 変更のたびに予期しない副作用が発生。8チーム中6チームがこのファイルを日常的に変更し、マージコンフリクトが週平均12件発生。
- 循環依存: テストの独立実行が不可能。order_serviceのテストにpayment_serviceのモックが必須で、テスト実行時間の30%を占める。
- Shared DB: スキーマ変更が全チームに影響。カラム追加でも全チームの承認が必要で、リードタイム平均2週間。
Mission 2: 技術的負債ヒートマップ作成(15分)
要件
以下のメトリクスを使用して、ShopMasterの技術的負債ヒートマップを作成してください。
変更頻度(過去6ヶ月のコミット数):
order.rb: 342
product.rb: 156
user.rb: 89
payment.rb: 201
orders_controller.rb: 178
order_service.rb: 234
payment_service.rb: 198
バグ発生数(過去6ヶ月):
order.rb: 28
product.rb: 8
user.rb: 4
payment.rb: 15
orders_controller.rb: 12
order_service.rb: 19
payment_service.rb: 16
循環的複雑度(平均):
order.rb: 45
product.rb: 18
user.rb: 12
payment.rb: 32
orders_controller.rb: 25
order_service.rb: 38
payment_service.rb: 29
解答例
技術的負債スコア = 変更頻度 × バグ率 × 複雑度係数
| ファイル | 変更頻度 | バグ率 | 複雑度係数 | 負債スコア | リスクレベル |
|---|---|---|---|---|---|
| order.rb | 342 | 8.2% | 2.25 | 63.1 | 🔴 Critical |
| order_service.rb | 234 | 8.1% | 1.90 | 36.0 | 🔴 Critical |
| payment_service.rb | 198 | 8.1% | 1.45 | 23.2 | 🟠 High |
| payment.rb | 201 | 7.5% | 1.60 | 24.1 | 🟠 High |
| orders_controller.rb | 178 | 6.7% | 1.25 | 14.9 | 🟡 Medium |
| product.rb | 156 | 5.1% | 0.90 | 7.2 | 🟢 Low |
| user.rb | 89 | 4.5% | 0.60 | 2.4 | 🟢 Low |
ヒートマップの解釈:
graph TD
subgraph HH["高バグ率 × 高変更頻度\n最優先で分割"]
A1["order.rb\norder_svc"]
end
subgraph HL["高バグ率 × 低変更頻度"]
A2["payment.rb\npayment_svc"]
end
subgraph LH["低バグ率 × 高変更頻度\n次フェーズで対応"]
A3["orders_controller"]
end
subgraph LL["低バグ率 × 低変更頻度\n現状維持可"]
A4["product.rb"]
A5["user.rb"]
end
style HH fill:#fee2e2,stroke:#dc2626,stroke-width:3px,color:#991b1b
style HL fill:#fef3c7,stroke:#d97706,stroke-width:2px,color:#92400e
style LH fill:#fef3c7,stroke:#d97706,color:#92400e
style LL fill:#d1fae5,stroke:#059669,color:#065f46
style A1 fill:#fee2e2,stroke:#dc2626,color:#991b1b
style A2 fill:#fef3c7,stroke:#d97706,color:#92400e
style A3 fill:#fef3c7,stroke:#d97706,color:#92400e
style A4 fill:#d1fae5,stroke:#059669,color:#065f46
style A5 fill:#d1fae5,stroke:#059669,color:#065f46
推奨アクション: order.rb と order_service.rb を最優先で分割。この2ファイルだけでバグの47%、マージコンフリクトの60%を占めている。
Mission 3: モジュール間依存グラフの作成(15分)
要件
ShopMasterの主要モジュール間の依存関係を可視化し、結合度を評価してください。
解答例
依存グラフ:
graph TD
OM["Order<br/>Model"] --> OS["OrderService"]
OS --> PS["PaymentSvc<br/>(循環依存!)"]
PS --> OS
OM --> NS["NotificationService<br/>(全サービスから直接依存)"]
OS --> IS["InventorySvc"]
OS --> NS
IS --> NS
PS --> NS
OM --> DB["PostgreSQL(単一DB)<br/>300テーブル、全モジュールが共有"]
OS --> DB
IS --> DB
PS --> DB
NS --> DB
classDef danger fill:#fee,stroke:#c33,color:#333
classDef warning fill:#fff3cd,stroke:#f0ad4e,color:#333
classDef db fill:#e8f4fd,stroke:#2196f3,color:#333
class PS danger
class NS warning
class DB db
結合度メトリクス:
| モジュールペア | 結合タイプ | 結合度 | 問題点 |
|---|---|---|---|
| OrderSvc ↔ PaymentSvc | 循環依存 | 極高 | テスト・デプロイが独立不可 |
| 全モジュール → NotificationSvc | スタンプ結合 | 高 | 通知変更が全体に波及 |
| 全モジュール → PostgreSQL | 共有DB結合 | 高 | スキーマ変更の影響大 |
| Order → Inventory | データ結合 | 中 | 在庫確認のためのSQL JOIN |
凝集度評価:
| モジュール | 凝集度 | 理由 |
|---|---|---|
| Order | 低(論理的凝集) | 注文・カート・返品・レビューが混在 |
| Payment | 中(機能的凝集) | 決済処理に集中だがStripe直結 |
| User | 高(機能的凝集) | ユーザー管理に集中 |
Mission 4: 移行アセスメントレポート作成(15分)
要件
上記の分析結果をもとに、マイクロサービス移行のアセスメントレポートを作成してください。
解答例
# ShopMaster マイクロサービス移行アセスメントレポート
## 1. エグゼクティブサマリー
ShopMasterは5年間の成長により、モノリスの限界に達している。
デプロイ頻度(月2回)がビジネス要求(週次リリース)に追いつかず、
障害復旧時間(4時間)がSLO(30分)を大幅に超過している。
移行推奨度: ★★★★☆(強く推奨)
## 2. 現状の問題(定量データ)
| 指標 | 現状 | 目標 | ギャップ |
|------|------|------|---------|
| デプロイ頻度 | 月2回 | 週1回以上 | 2倍以上 |
| ビルド時間 | 45分 | 10分以内 | 4.5倍 |
| テスト時間 | 2時間 | 20分以内 | 6倍 |
| MTTR | 4時間 | 30分 | 8倍 |
| マージコンフリクト | 週12件 | 週2件以下 | 6倍 |
## 3. 移行の推奨フェーズ
### Phase 1(3ヶ月): Strangler Fig開始
- NotificationServiceをイベント駆動に分離
- APIゲートウェイの導入
- CI/CDパイプラインの分離準備
### Phase 2(6ヶ月): コアサービス分離
- Order/Payment の循環依存解消
- Orderサービスの独立(DB分離含む)
- Paymentサービスの独立
### Phase 3(6ヶ月): 完全移行
- 残りモジュールの段階的分離
- 共有DBの完全分離
- モノリスの廃止
## 4. リスク評価
| リスク | 影響度 | 発生確率 | 対策 |
|--------|--------|---------|------|
| データ整合性の喪失 | 高 | 中 | Sagaパターン導入 |
| 運用複雑度の増大 | 中 | 高 | SREチーム組成 |
| チームスキル不足 | 中 | 中 | 段階的研修 |
## 5. 必要リソース
- 専任移行チーム: 5名 × 15ヶ月
- インフラ追加コスト: 月額約50万円増
- 研修コスト: 約200万円
まとめ
| ポイント | 内容 |
|---|---|
| アンチパターン | 定量データで問題を特定する |
| ヒートマップ | 変更頻度×バグ率×複雑度で優先度を決める |
| 依存グラフ | 結合度と凝集度を可視化する |
| アセスメント | 現状・目標・ギャップを定量的に示す |
チェックリスト
- モノリスのアンチパターンを3つ以上特定できた
- 技術的負債ヒートマップを作成できた
- モジュール間の依存関係を図示できた
- 移行アセスメントレポートを作成できた
次のステップへ
次はチェックポイントクイズでモノリス分析の理解度を確認します。
推定読了時間: 60分