要点: ResilienceはRetry回数ではなく、有限Budgetを意図的に使うことです。
課題
無Timeout、多層Retry、誤ったBreaker、Shared PoolがFailureを増幅します。
単純な対策だけでは不十分な理由
三Layer三Retryは27 Attemptになります。
Timeout・Bulkheadは発見中、Circuitは既知Failureから守ります。
処理フロー
残Budget→Bulkhead
分離Concurrency→Attempt
Timeout・Idempotency→Circuit
Controlled Failure
アーキテクチャ上の判断
Journey Budget
残時間をDownstreamへ配分します。
Error SemanticsでRetry
Validationや非Idempotent WriteはRetryしません。
Pool分離
遅いVendorを他Dependencyから隔離します。
さらに深く考える
FallbackはProduct判断
誤情報よりUnavailableが安全な場合があります。
Adaptive Limit Guardrail
Min、Max、Slow Recoveryを使います。
実装手順
- 一つのDeadlineを伝播します。
- TransientでIdempotentな処理だけRetryします。
- Dependency別PoolでLoad Shedします。
技術例: Deadline-aware Call
remaining = request.deadline - now()
if remaining < minimumUsefulTime: return degraded()
with bulkhead.acquire(timeout = 20ms):
return retry(max = 2, jitter = true) {
vendor.call(timeout = min(300ms, remaining))
}Attemptごとに残Deadlineを再計算します。
想定すべき障害パターン
- FallbackがStale過多です。
- Half-open Probeが多すぎます。
- Client離脱後もRetryします。
監視すべきシグナル
| シグナル | 確認する理由 |
|---|---|
| Dependency別Deadline消費 | Budget消費先です。 |
| Retry Amplification | Request当たりAttemptです。 |
| Bulkhead Reject・Circuit | 封じ込め状態です。 |
設計の検証方法
- Failure種別を個別注入します。
- 一Dependency Failure時の他Poolを確認します。
- 部分復旧を試験します。
安全なRollout計画
計測、Timeout、Pool分離、限定Retry、Observe-only Circuitの順で導入します。
本番前チェックリスト
- Retry Ownerは一Layerです。
- CircuitにOverrideとProbeがあります。
- FallbackのFreshnessを明示します。
まとめ
既知Budget内にFailureを封じ、正常WorkのCapacityを守ります。
