プレイブック

決済担当者向けの再試行アルゴリズム (Retry Algorithms For Payment Workers)

指数バックオフ、ジッター、キャップ、遅延と再試行の違い、サーキット ブレーカー - 前のセクションの分類法を実用的なコードに変換します。

分散型決済エンジン

一部 12 の 22

取得と完了の間のギャップを埋める一連の分散型支払いアーキテクチャ。

Distributed payment engine architecture diagram

前のセクションでは 4 つのエラー カテゴリを定義しました。このセクションでは、再試行可能な 3 つのカテゴリ (タイムアウト後のクエリ、レート制限、インフラストラクチャ)、つまり待機時間、試行回数、完全に停止してサーキット ブレーカーをオンにするタイミングに関する実際のアルゴリズムを設定します。```text Attempt 1 → başarısız → bekle (backoff) → Attempt 2 → başarısız → bekle (daha uzun) → Attempt 3 → başarısız → cap'e ulaşıldı → defer / dead-letter


## 最初に説明した概念```text
📦 Exponential Backoff
Her denemede bekleme süresini katlayarak artıran strateji: base * 2^attempt.

📦 Jitter
Backoff süresine eklenen rastgele sapma; çok sayıda worker'ın aynı anda tekrar denemesini (thundering herd) önler.

📦 Cap
Bekleme süresinin ve/veya deneme sayısının üst sınırı; sonsuz retry döngüsünü engeller.

📦 Circuit Breaker
Bir bağımlılık sürekli başarısız olduğunda istekleri tamamen durduran, zamanla yeniden deneyen koruma mekanizması.
```ジッターのないバックオフにより、同時に失敗した何百ものジョブが同じミリ秒以内に再試行され、すでにストレスがかかっている PSP はさらに悪い状況に陥ります。

## バックオフの公式と、常に待機するだけでは不十分な理由

固定の 1 秒待機は単純ですが、2 つの問題があります。PSP が短いバーストを実行している場合、1 秒では十分ではない可能性があります。 PSPがすでに回復している場合、1秒は不必要な遅さです。指数バックオフは、最初の試行では高速ですが、その後の試行ではより慎重になります。```text
delay = min(cap, base * 2^attempt) + random(0, jitterRange)

attempt 0 → ~200ms
attempt 1 → ~400ms
attempt 2 → ~800ms
attempt 3 → ~1600ms
...
attempt N → cap'e ulaşır (örn. 30s)
```ジッターを追加しないと、この式は危険です。同時に失敗したすべてのワーカーは、正確に 200 ミリ秒、400 ミリ秒、800 ミリ秒後に再試行し、同期ウェーブで PSP にヒットします。ランダムな量 (`full jitter` または `decorrelated jitter`) を追加すると、この波が放射されます。

## 再試行と延期の違い

**再試行**。ワーカーは短い待機後 (通常は数秒以内)、同じプロセスで同じリクエストを再試行します。 **遅延** とは、ジョブがデータベースまたはキューに戻され、一定期間 (数分、場合によっては数時間) 後に再び処理されることです。レート制限エラーは通常、再試行によって解決されます。しかし、PSP 自体が大規模な停止に見舞われている場合、再試行ループに数分留まるとワーカーとリソースが枯渇します。その時点で、ジョブをしばらく「スリープ」状態にするための延期はより安全な方法です。```text
Rate limited → retry (saniyeler, backoff ile)
Uzun süreli PSP kesintisi → defer (dakikalar, ayrı bir zamanlanmış tekrar)
```## サーキットブレーカー: 完全に試すのをやめるべきとき

依存関係へのリクエストが繰り返し失敗すると、新しいリクエストはそれぞれ既知の結果を再現するだけです。リソースを消費し、遅延が増加するだけです。サーキットブレーカーは次の 3 つの状態で動作します。```text
Closed   → istekler normal şekilde gönderilir
  │ hata eşiği aşıldı
  ▼
Open     → istekler hemen reddedilir, PSP'ye hiç gitmez
  │ soğuma süresi geçti
  ▼
Half-Open → sınırlı sayıda deneme istek gönderilir
  ├─ başarılı → Closed
  └─ başarısız → Open
```サーキット ブレーカーは再試行に代わるものではありません。リトライにより無駄が発生する瞬間を早期に検知する上位層です。ブレーカーがオンになっている間、作業者は延期されたキューに誘導し、無駄に作業を続けないようにする必要があります。

## 試行回数、上限

これらの数値は任意であってはなりません。これは、PSP 自体の SLA とその仕事のビジネス価値に見合ったものである必要があります。高額の支払いの場合、8 ~ 10 回の試行と合計 5 分のウィンドウが妥当な場合があります。優先度の低いバックグラウンド プロセスの場合は、3 回の試行で十分な場合があります。

## 混同されやすい区別```text
❌ Retry = defer
✓ Retry saniyeler içinde aynı process'te olur; defer işi dakikalarca bekletir

❌ Jitter isteğe bağlı bir iyileştirmedir
✓ Jitter'sız backoff, thundering herd riskini gerçek hale getirir

❌ Circuit breaker retry'ın alternatifidir
✓ Circuit breaker, retry'ı ne zaman durduracağını söyleyen üst katmandır
```## フル ジッターとジッターなしのバックオフ

|基準 |ジッターフリー |フルジッター |
| --- | --- | --- |
|同期波のリスク |高 |低い |
| PSPでのロードパターン |突然のピーク |散在 |
|アプリケーションの複雑さ |低い |それほど高くない |

## 再試行アルゴリズムを設定するときのチェックリスト

1. バックオフ式に上限はありますか? それとも理論的にはクールダウンは無限に増加する可能性がありますか?
2. ジッターが適用されていますか? それともすべてのワーカーが同時に再試行していますか?
3. レート制限と長期中断の間の再試行/延期には区別がありますか?
4. サーキット ブレーカーがオンになっているとき、ワーカーは本当に PSP へのリクエストの送信を停止しますか?
5. 試行回数と合計ウィンドウは、ジョブの実際のジョブ値によって決定されましたか? それとも乱数ですか?
6. サーキットブレーカーの開/半開/閉の遷移は計量的に監視されていますか?

## この記事で覚えておくべきこと

1. 指数バックオフだけでは十分ではありません。ジッターのない同期波を生成します。
2. Retry と defer は同じ動詞ではありません。1 つは秒単位、もう 1 つは分-時間単位です。
3. サーキット ブレーカーは再試行に代わるものではなく、再試行が無駄になることを早期に通知する保護層です。
4. 試行回数と上限は、ジョブの実際の価値に応じて意識的に選択する必要があります。

> 優れた再試行アルゴリズムは失敗を隠しません。失敗のコストを制御します。

次のセクションでは、これらの再試行がどのように機能するのかについて説明します。データベースを使用したジョブ キューとリース メカニズムは、同じジョブが 2 つのワーカーによって同時に処理されることをどのように防止するのでしょうか。

FAQ

よくある質問

指数バックオフとは何ですか?

試行ごとに待機時間を指数関数的に増加させる戦略: 基本 * 2^ 試行。

ジッターとは何ですか?

ランダムな偏差がバックオフ時間に追加されます。これにより、複数のワーカーが同時に再試行すること (雷鳴の群れ) が防止されます。

「再試行=遅延」は正しいですか?

再試行は同じプロセスで数秒以内に行われます。 defer はジョブを数分間待機させます

このセクションでは何を修正しますか?

ここで 2 つの異なる動詞を混同しないでください。 **retry** は同じワーカー内ですぐに再試行します。 **延期**の場合は、ジョブをしばらく待機させてから、キューに戻します。どちらも「もう一度やり直せ」のように聞こえますが、タイミングと責任が異なります。指数関数的バックオフだけでは十分ではありません。ジッターのない同期波を生成します。前のセクションでは 4 つのエラー カテゴリを定義しました。このセクションでは、再試行可能な 3 つのカテゴリ (タイムアウト後のクエリ、レート制限、インフラストラクチャ)、つまり待機時間、試行回数、完全に停止してサーキット ブレーカーをオンにするタイミングに関する実際のアルゴリズムを設定します。

学んだエンジニアリング原則

  • ジッターのないバックオフにより、同期障害の波が生成されます。
  • Retry は秒、defer は分~時間です。同じ動詞ではありません。
  • サーキットブレーカーは、再試行が無駄になった場合に早期に停止します。

続きを読む

続きを読む

シリーズの次のシリーズ

シリーズの次のシリーズ

エッセイ

支払いエラーの分類法

タイムアウト、429、5xx、ビジネスの低下とインフラストラクチャのエラーは同じものではありません。カテゴリごとに異なる再試行ポリシーが必要です。

同じシリーズ

エッセイ

支払調整員建設

スイーパーによるドリフトの改善方法: PSP が成功している間、ローカル登録が期限切れになる可能性があります。古い FinalizePending を回復する方法。

Paylaş