状態レビュー中 担当プラットフォームチーム 対象注文 · 在庫 · 決済 · 配送

概要

注文・在庫・決済・配送を 1 つのアプリケーション(モジュラーモノリス)として動かし、データベースは 1 つに保つ。コンテキストをまたぐ処理は、注文のトランザクションで記録したイベントをキュー経由でワーカーが進める。

サービス分割は見送る。チームは 1 つで、デプロイの独立性より、在庫引当と注文確定を同じトランザクションで扱えることを優先する。

システム構成

モジュールの境界

モジュール同士は公開インターフェースだけを呼び、他のモジュールのテーブルを直接読まない。依存は注文から他へ向かう一方向に揃え、逆向きの連絡はイベントで返す。

非同期処理

状態の更新とイベントの記録は同じトランザクションで行い(outbox)、キューへの送信は relay に任せる。配送は at-least-once なので、ジョブはすべて冪等に作る。

  • 外部サービスへの要求は、注文 ID から作った冪等キーを付けて送る。
  • タイムアウトした要求は、結果を照会してから再送する。再試行は指数バックオフで最大 24 時間。
  • 上限に達したメッセージは DLQ に移し、Backoffice の要対応一覧に出す。

インフラ構成

層 構成 スケール
リージョン 東京リージョン(ap-northeast-1)、2 AZ 大阪へは DB のスナップショットだけを複製
App (API) ECS on Fargate、各 AZ に最低 2 タスク CPU 60% でスケールアウト、上限 20 タスク
Worker / relay API と同じイメージを別の ECS サービスで起動 キューの滞留数でスケール、relay は 1 タスク固定
Aurora PostgreSQL Multi-AZ、リーダーインスタンス 1 Backoffice の一覧と集計はリーダーから読む
SQS 標準キュー + DLQ —

非機能要件

項目 目標 備考
可用性 注文確定 API 99.9% / 月 決済代行の障害は含めない
応答時間 注文確定 p95 800ms、キャンセル受付 p95 300ms キャンセルは返金を待たずに 202 を返す
ピーク セール時 300 注文 / 分 在庫引当の行ロック待ちを監視する
復旧 RPO 5 分、RTO 1 時間 ポイントインタイムリカバリ
整合性 支払済みの注文は必ず出荷指示か返金に到達する 30 分以上どちらにも進まない注文を検知する

可観測性

  • リクエストとジョブに注文 ID を載せ、API からワーカー、外部呼び出しまでを 1 本のトレースで追う。
  • outbox の未送信件数、キューの滞留時間、DLQ の件数をダッシュボードに出す。
  • DLQ への移動と「返金待ち」が 1 時間を超えた注文は、当番に通知する。

未決事項

  1. 配送業者の Webhook を API で受けるか、専用の受け口を分けるか。
  2. セール時の在庫引当を行ロックのまま続けるか、在庫数を別のストアに逃がすか。
  3. 大阪リージョンへの切り替えを手順書で済ませるか、自動化するか。