ストーリー
佐藤CTOがダッシュボードの画面を見せました。数百のメトリクスが並ぶグラフ群。
OpenTelemetryによる統合可観測性
3つの柱の統合
NexPayでは、OpenTelemetry(OTel)を標準として、メトリクス・ログ・トレースの3つの柱を統合します。
NexPay 可観測性アーキテクチャ:
[各サービス] ── OTel SDK ──┐
│
┌───────▼────────┐
│ OTel Collector │
│ (DaemonSet) │
└───┬────┬───┬───┘
│ │ │
┌───────────┘ │ └───────────┐
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Prometheus │ │ Grafana │ │ Jaeger / │
│ (Metrics) │ │ Loki (Logs) │ │ Tempo │
│ │ │ │ │ (Traces) │
└──────┬───────┘ └──────┬───────┘ └──────┬───────┘
│ │ │
└────────────────┼────────────────┘
▼
┌──────────────┐
│ Grafana │
│ Dashboard │
└──────────────┘
OTelの計装設計
// NexPay OpenTelemetry計装設計
interface OTelInstrumentationDesign {
// 自動計装(ベースライン)
autoInstrumentation: {
http: "受信/送信HTTPリクエストの自動トレース";
grpc: "gRPC呼び出しの自動トレース";
database: "SQLクエリの自動トレース(パラメータはマスク)";
messaging: "Kafka/SQSメッセージの自動トレース";
};
// カスタム計装(ビジネスロジック)
customInstrumentation: {
paymentFlow: {
spans: [
"payment.authorize",
"payment.risk_check",
"payment.tokenize",
"payment.process",
"payment.settle"
];
attributes: {
"payment.method": "QR | NFC | ONLINE";
"payment.amount_range": "SMALL | MEDIUM | LARGE";
"payment.merchant_category": "string";
"payment.risk_score": "number";
};
};
transferFlow: {
spans: [
"transfer.validate",
"transfer.aml_check",
"transfer.debit",
"transfer.credit",
"transfer.notify"
];
};
};
// センシティブデータのマスク
dataMasking: {
rules: [
"カード番号: 下4桁のみ表示",
"口座番号: ハッシュ化",
"電話番号: マスク",
"金額: 範囲に変換(SMALL/MEDIUM/LARGE)"
];
};
}
決済フローの分散トレーシング
エンドツーエンドのトレース設計
決済フロー トレース例:
Trace ID: abc123-def456-ghi789
[API Gateway] ──── 2ms ────┐
▼
[Payment Service] ┌── authorize ── 15ms
│ │ ├── risk_check ── 8ms
│ │ └── fraud_detection ── 5ms
│ │
├── [Tokenization GW] ├── tokenize ── 3ms
│ │
├── [Card Network] ├── external_auth ── 120ms ←★ 外部依存
│ │
├── [Account Service] ├── debit ── 10ms
│ └── [Aurora DB] │ └── db_update ── 4ms
│ │
└── [Notification Svc] └── notify ── 5ms
└── push_send ── 3ms
合計: 168ms (p50), 280ms (p95), 650ms (p99)
Trace Contextの伝播
# Trace Context伝播設計
trace_propagation:
# 同期通信(HTTP/gRPC)
synchronous:
format: "W3C Trace Context"
headers:
- "traceparent"
- "tracestate"
# 非同期通信(Kafka/SQS)
asynchronous:
format: "メッセージヘッダーにTrace Context埋め込み"
kafka_headers:
- key: "traceparent"
value: "00-{traceId}-{spanId}-{flags}"
sqs_attributes:
- name: "TraceParent"
type: "String"
# 外部システム連携
external:
card_network: "Correlation IDで紐付け(Trace Contextなし)"
bank_api: "Request IDで紐付け"
strategy: "外部呼び出しのSpanに外部のCorrelation IDをAttributeとして付与"
SLI/SLO設計
NexPayのSLI/SLO定義
| サービス | SLI | SLO | 計測方法 |
|---|---|---|---|
| 決済API | レスポンスタイム(p99) | < 800ms | Istio + Prometheus |
| 決済API | 成功率 | > 99.95% | HTTP 2xx / 全リクエスト |
| 決済API | 可用性 | > 99.99% | ヘルスチェック成功率 |
| 送金API | レスポンスタイム(p99) | < 1,000ms | Istio + Prometheus |
| 送金API | 成功率 | > 99.9% | HTTP 2xx / 全リクエスト |
| 投資API | レスポンスタイム(p99) | < 2,000ms | Istio + Prometheus |
| 投資API | 可用性 | > 99.9% | ヘルスチェック成功率 |
| 残高照会 | レスポンスタイム(p99) | < 200ms | Istio + Prometheus |
エラーバジェットの管理
// NexPayエラーバジェット設計
interface ErrorBudgetDesign {
// 決済APIのエラーバジェット計算
paymentApi: {
slo: "99.99%可用性";
period: "30日間(ローリング)";
totalMinutes: 43200; // 30日 × 24時間 × 60分
allowedDowntime: "4.32分/月";
// バジェット消費アラート
alerts: {
warning: "50%消費(残り2.16分)";
critical: "80%消費(残り0.86分)";
exhausted: "100%消費 → デプロイ凍結";
};
};
// エラーバジェットポリシー
policy: {
budgetRemaining: {
">50%": "通常リリースサイクル";
"20-50%": "リスクの高いデプロイは承認制";
"<20%": "重大バグ修正のみデプロイ許可";
"0%": "全デプロイ凍結。信頼性改善に集中";
};
};
}
ダッシュボード設計
Grafanaダッシュボード構成
| ダッシュボード名 | 対象者 | 主要パネル |
|---|---|---|
| Executive Overview | 経営層 | 月間取引額、成功率、SLO達成率 |
| Payment Operations | 運用チーム | リアルタイムTPS、エラー率、レイテンシ |
| Service Health | SRE | サービス別の健全性、Pod数、リソース使用率 |
| Security Monitor | セキュリティ | 不正検知数、認証失敗、WAFブロック数 |
| Business Metrics | PdM | DAU、ARPU、機能別利用率 |
アラート設計
# NexPayアラート設計
alerting:
# アラートの分類
severity_levels:
P1_critical:
description: "決済基盤の停止。ユーザー影響あり"
examples:
- "決済成功率が99%を下回った"
- "決済APIの応答時間p99が3秒を超えた"
response_time: "5分以内にオンコール対応"
notification: "PagerDuty → 電話 + Slack #incident"
P2_high:
description: "部分的なサービス劣化。一部ユーザーに影響"
examples:
- "送金サービスのエラー率が1%を超えた"
- "投資サービスの応答が遅延している"
response_time: "15分以内にオンコール確認"
notification: "PagerDuty → Slack #alerts"
P3_medium:
description: "潜在的な問題。現時点でユーザー影響なし"
examples:
- "DBコネクションプールの使用率が80%超過"
- "ディスク使用率が70%超過"
response_time: "営業時間内に対応"
notification: "Slack #monitoring"
P4_low:
description: "改善推奨。運用効率に影響"
examples:
- "キャッシュヒット率が低下傾向"
- "非効率なクエリの検出"
response_time: "次回スプリントで対応検討"
notification: "Slack #ops-improvement"
# アラート疲れ防止
anti_fatigue:
deduplication: "同一アラートは5分間集約"
auto_resolve: "自動復旧したアラートは自動クローズ"
escalation: "15分未対応のP1は自動エスカレーション"
インシデント対応フロー
NexPayインシデント管理
インシデント対応フロー:
[アラート発火]
│
▼
[自動分類] ─── P1? ──→ [自動: 決済APIへのトラフィック制限]
│ │
│ No ▼
│ [PagerDutyオンコール呼出]
▼ │
[Slack通知] ▼
│ [インシデントコマンダー指名]
▼ │
[手動トリアージ] ▼
[戦争部屋(War Room)開設]
│
┌──────┴──────┐
│ 並行作業 │
│ ・原因調査 │
│ ・影響範囲特定│
│ ・暫定対応 │
└──────┬──────┘
│
[復旧確認]
│
[ポストモーテム(72h以内)]
「フィンテックのインシデントは、毎秒の遅延が金銭的損失に直結する。だからこそ、“検知→判断→復旧”のサイクルを極限まで短くする設計が求められる」 — 佐藤CTO
まとめ
| ポイント | 内容 |
|---|---|
| OpenTelemetry | メトリクス・ログ・トレースを統合。全サービスにOTel SDKを導入 |
| 分散トレーシング | 決済フロー全体をTraceで可視化。外部呼び出しもCorrelation IDで紐付け |
| SLI/SLO | サービスティアに応じたSLOを設定。エラーバジェットでリリース判断 |
| ダッシュボード | ステークホルダー別に5種類のダッシュボードを提供 |
| アラート | P1-P4の4段階。アラート疲れ防止策を組み込む |
| インシデント対応 | 自動分類 + 自動緩和で初動を短縮。ポストモーテム文化を確立 |
チェックリスト
- OpenTelemetryの3つの柱(メトリクス、ログ、トレース)の統合設計を理解した
- 決済フローの分散トレーシング設計を把握した
- NexPayのSLI/SLO定義とエラーバジェット管理を設計できた
- アラート設計(4段階の重大度、疲れ防止)を理解した
- インシデント対応フローを把握した
次のステップへ
次は「パフォーマンスとスケーラビリティ設計」に進みます。月間10億件のトランザクションを処理するためのキャッシュ戦略とオートスケーリングを設計しましょう。
推定読了時間: 40分