ストーリー
高橋アーキテクト がホワイトボードの前に立ちました。
ミッション概要
| 項目 | 内容 |
|---|---|
| 題材 | オンラインフードデリバリーサービス |
| 目標 | マイクロサービスアーキテクチャを設計する |
| 所要時間 | 90分 |
| 成果物 | アーキテクチャ図、API設計、通信方式の選定理由 |
ミッション 1: サービスの分割(20分)
以下の機能要件を持つフードデリバリーサービスを、適切なマイクロサービスに分割してください。
機能要件:
- ユーザー登録・認証
- レストラン情報の管理・検索
- メニュー管理
- 注文の作成・管理
- 決済処理
- 配達員のマッチング・配送追跡
- レビュー・評価
- プッシュ通知
設計すべきこと:
- サービスの一覧と各サービスの責務
- 各サービスが所有するデータ
- 分割の理由(DDD境界づけられたコンテキスト)
ヒントと模範回答
サービス分割例:
1. Identity Service
- 責務: ユーザー登録、認証、認可
- データ: users, roles, tokens
2. Restaurant Service
- 責務: レストラン情報、メニュー管理
- データ: restaurants, menus, business_hours
3. Order Service
- 責務: 注文のライフサイクル管理
- データ: orders, order_items, order_status
4. Payment Service
- 責務: 決済処理、返金
- データ: payments, refunds, payment_methods
5. Delivery Service
- 責務: 配達員マッチング、配送追跡
- データ: drivers, deliveries, locations
6. Review Service
- 責務: レビュー・評価管理
- データ: reviews, ratings
7. Notification Service
- 責務: プッシュ通知、メール、SMS
- データ: notification_templates, notification_logs
分割理由:
- 各サービスは独立した業務ドメイン
- 変更頻度が異なる(メニューは頻繁、認証はまれ)
- スケーリング要件が異なる(検索は高負荷、レビューは低負荷)
ミッション 2: 通信方式の選定(20分)
各サービス間の通信方式(同期/非同期)を決定し、その理由を記述してください。
検討すべき通信:
- 注文作成時の在庫確認
- 注文確定後の決済
- 決済完了後の配達員マッチング
- 注文ステータス変更時の通知
- レストラン検索
ヒントと模範回答
// 通信方式の選定
const communicationDesign = {
// 1. 注文 → レストラン: 同期(REST)
// 理由: メニューの在庫をリアルタイムで確認し、ユーザーに即座に結果を返す
orderToRestaurant: { type: "sync", protocol: "REST" },
// 2. 注文 → 決済: 同期(gRPC)
// 理由: 決済結果を待って注文を確定する必要がある。高速性のためgRPC
orderToPayment: { type: "sync", protocol: "gRPC" },
// 3. 注文 → 配送: 非同期(イベント)
// 理由: 配達員マッチングは時間がかかる。注文確定後に非同期で実行
orderToDelivery: { type: "async", protocol: "EventBus", event: "order.confirmed" },
// 4. 各サービス → 通知: 非同期(イベント)
// 理由: 通知は遅延許容。1つのイベントで複数通知を送信
anyToNotification: { type: "async", protocol: "EventBus" },
// 5. クライアント → レストラン検索: 同期(REST)
// 理由: 検索結果を即座にユーザーに表示
searchRestaurant: { type: "sync", protocol: "REST" },
};
ミッション 3: API Gateway設計(15分)
API Gatewayの設計を行ってください。
設計すべきこと:
- ルーティングテーブル
- 認証フロー
- レート制限ポリシー
- BFFの集約エンドポイント(1つ以上)
ヒントと模範回答
// ルーティングテーブル
const routes = [
{ path: "/api/auth/**", service: "identity-service", auth: false },
{ path: "/api/restaurants/**", service: "restaurant-service", auth: false },
{ path: "/api/orders/**", service: "order-service", auth: true },
{ path: "/api/payments/**", service: "payment-service", auth: true },
{ path: "/api/deliveries/**", service: "delivery-service", auth: true },
{ path: "/api/reviews/**", service: "review-service", auth: true },
];
// レート制限
const rateLimits = {
anonymous: { requests: 30, window: "1m" },
authenticated: { requests: 100, window: "1m" },
premium: { requests: 500, window: "1m" },
};
// BFF集約エンドポイント
app.get("/api/bff/order-summary/:orderId", async (req, res) => {
const [order, restaurant, delivery] = await Promise.all([
orderService.getOrder(req.params.orderId),
restaurantService.getRestaurant(order.restaurantId),
deliveryService.getDeliveryStatus(req.params.orderId),
]);
res.json({
order: { id: order.id, items: order.items, total: order.total },
restaurant: { name: restaurant.name, address: restaurant.address },
delivery: { status: delivery.status, eta: delivery.estimatedArrival },
});
});
ミッション 4: サービスディスカバリ設計(15分)
サービスディスカバリとロードバランシングの設計を行ってください。
検討すべきこと:
- ディスカバリ方式の選択と理由
- ヘルスチェックの設計
- ロードバランシングアルゴリズムの選択
ヒントと模範回答
// Kubernetesを前提としたサーバーサイドディスカバリ
// → Kubernetes Serviceが自動的にLBとディスカバリを提供
// ヘルスチェック設計
const healthCheckConfig = {
// Liveness Probe: サービスが生きているか
liveness: {
path: "/health/live",
interval: 10, // 10秒ごと
timeout: 3, // 3秒でタイムアウト
failureThreshold: 3, // 3回失敗で再起動
},
// Readiness Probe: リクエストを受けられるか
readiness: {
path: "/health/ready",
interval: 5,
timeout: 3,
failureThreshold: 2,
},
};
// ロードバランシング
const lbConfig = {
restaurantSearch: "round-robin", // 均等分散
orderService: "least-connections", // 処理時間が不均一
deliveryService: "ip-hash", // 配達員のセッション維持
};
ミッション 5: 設定管理設計(10分)
分散設定管理の戦略を設計してください。
ヒントと模範回答
// 設定の分類
const configStrategy = {
// 環境変数(Kubernetes ConfigMap)
envVars: ["PORT", "LOG_LEVEL", "SERVICE_NAME"],
// シークレット(AWS Secrets Manager)
secrets: ["DB_PASSWORD", "API_KEYS", "JWT_SECRET"],
// 動的設定(AWS AppConfig)
dynamicConfig: {
"feature.new_matching_algorithm": { type: "boolean", default: false },
"config.order_timeout_seconds": { type: "number", default: 300 },
"config.max_delivery_radius_km": { type: "number", default: 10 },
},
};
ミッション 6: アーキテクチャ図の作成(10分)
上記すべてを統合したアーキテクチャ図をテキストで描いてください。
ヒントと模範回答
[Client App]
│
[API Gateway]
├─ 認証
├─ レート制限
└─ BFF集約
│
┌───────────────┼───────────────┐
│ │ │
[Identity] [Restaurant] [Order]
[Service] [Service] [Service]
│ │ │
│ │ ┌────┴────┐
│ │ │ │
│ │ [Payment] [Delivery]
│ │ [Service] [Service]
│ │ │ │
└───────┬───────┴──────────┴─────────┘
│
[Event Bus]
│
┌───────┴───────┐
│ │
[Notification] [Review]
[Service] [Service]
── 同期(REST/gRPC)
── 非同期(Event Bus)
横断的関心事:
[Service Registry] [Config Server] [Secret Manager]
達成チェックリスト
- 7つ以上のマイクロサービスに適切に分割できた
- 各通信の同期/非同期を理由とともに選定できた
- API Gatewayのルーティングと認証を設計できた
- サービスディスカバリとヘルスチェックを設計できた
- 設定管理戦略を策定できた
- 全体のアーキテクチャ図を描けた
推定所要時間: 90分