GH GambleHub

Webhooks:リプレイと謝辞

1)基本的な配達モデル

At-less-once(デフォルト)-イベントは1回≥配信されます。正確に一度の保証は受信機のidempotencyによって達成されます。
Acknowledgement (ACK):受信者からの2xx(通常は200/204)のみが成功を意味します。他のすべては失敗として解釈され、繰り返しにつながります。
高速ACK:完全なビジネス処理の後ではなく、順番にイベントを配置した後に2xxに応答します。

2)イベントフォーマットと必須見出し

ペイロード(例)

json
{
"id": "evt_01HXYZ",
"type": "order. created",
"occurred_at": "2025-11-03T18:10:12Z",
"sequence": 128374,
"source": "orders",
"data": { "order_id": "o_123", "amount": "49. 90", "currency": "EUR" },
"schema_version": 1
}

送信ヘッダー

'X-Webhook-Id: evt_01HXYZ'-一意のイベントID(重複除外に使用)。
'X-Webhook-Seq: 128374'-モノトーンシーケンス(サブスクリプション/テーマ別)。
'X-Signature: sha256=<base64 (hmac_sha256 (body、 secret))>'-HMAC- подпись。
'X-Retry: 0,1,2……'は試行番号です。
'X-Webhook-Version: 1'-契約バージョン管理。
(オプション)'Traceparent'-トレース相関。

受信者からの応答

2xx-正常に受け入れられました(この'id'にはそれ以上の繰り返しはありません)。
410 Gone-エンドポイントが削除/非アクティブ→送信者は再起動を終了し、サブスクリプションを無効にします。
429/5xx/timeout-送信者はリトレイポリシーに従って繰り返します。

3)再利用ポリシー

推奨バックオフラダー(+ジッター)

'1s、 3s、 10s、 30s、 2m、 10m、 30m、 2h、 6h、 24h'(限界の後で、例えば48-72時間)。

ルール:
  • 指数関数バックオフ+ランダムジッタ(± 20-30%)「群れ効果」を避ける。
  • 一時的な障害のためのエラーのクォーラム(たとえば、5xxまたはネットワークタイムアウトの場合は再試行)。
  • Respect 429:最小'min (Retry-Afterヘッダー、次のバックオフウィンドウ)'を設定します。

タイムアウトとサイズ

接続タイムアウト≤ 3-5秒。合計応答タイムアウト≤ 10秒

契約の下の本体のサイズ(例えば、≤ 256 KB)、そうでなければ413→ロジック「chunking」または「pull URL」。

4) Idempotencyと重複除外

Idempotent application:同じ'id'の処理の繰り返しは同じ結果を返す必要があります。
受信者側のデダップストレージ:ストア'(X-Webhook-Id、 processed_at、チェックサム)'TTL ≥リトレイウィンドウで(24-72時間)。
構成キー:複数のトピック→'(subscription_id、 event_id)'の場合。

5)順序および「丁度一度の効果」

分散システムの厳格な秩序を保証することは困難です。使用して下さい:
  • キーによるパーティション:同じ論理セット(例えば、'order_id')は常に配信の1つの「チャネル」にあります。
  • シーケンス:古い「X-Webhook-Seq」でイベントを拒否し、行方不明のイベントが到着する前に「駐車場」に入れます。
正確に一度の効果が達成されます:
  • 適用された操作のログ(outbox/inboxパターン)、
  • データベース内の'event_id'によるトランザクションのupsert、
  • 複雑なプロセスのサガ/補償。

6)ステータスコードによるエラー解決(表)

レスポンスコード送信者の値[アクション]
2xxACKが受信されました私たちは、配信を検討し、レトライを停止
4xx (410/429を除く)永続エラー(ペイロード/承認)DLQを入れて統合を通知する
410エンドポイントが削除/非推奨リトレイの停止、サブスクリプションの無効化
408/429一時的な過負荷/タイムアウトバックオフ/ジッタによって繰り返して下さい;Retry-Afterを検討する'
5xx一時サーバーエラーバックオフ/ジッタによる繰り返し
3xxWebhookにリダイレクトを使用しないコンフィギュレーションエラーとして扱う

7)チャネルの保証

各メッセージのHMAC署名。「タイムウィンドウ」(ミットとリプレイ攻撃)で受信機で確認します。
機密ドメイン(LCC/決済)のmTLS。
発信アドレスのIP allowlist、 TLS 1。2+、HSTS。
PII最小化:不要な個人データを送信しないでください。ログに偽装します。
シークレットの回転:2つの有効なキー(active/next)と'X-Key-Id'ヘッダーが現在のキーを示します。

8)キュー、DLQ、リプレイ

イベントは送信側の出力キュー/ログに書き込まれる必要があります(信頼性の高いリプレイのため)。
リトレイの最大値を超えた場合、イベントは原因とともにDLQ (Dead Letter Queue)に移動します。
Replay API(受信者/演算子用):RPS制限と追加の署名/承認を備えた'id'/時間範囲/件名で再送信します。

リプレイAPIの例(送信者):

POST /v1/webhooks/replay
{ "subscription_id": "sub_123", "from": "2025-11-03T00:00:00Z", "to": "2025-11-03T12:00:00Z" }
→ 202 Accepted

9)契約とバージョン

イベント('schema_version'フィールド)とトランスポート('X-Webhook-Version')をバージョン化します。
オプションとしてのみフィールドを追加します。削除-マイナーな移行と移行期間(デュアルライト)。
イベントタイプ、例、スキーマ(JSONスキーマ)、エラーコードを文書化します。

10)観察可能性およびSLO

送信者の主な指標:
  • 'delivery_success_rate' (2xx/すべての試行)、'first_attempt_success_rate'
  • 'retries_total'、 'max_retry_age_seconds'、 'dlq_count'
  • 'latency_p50/p95' (occurred_at→ack_received_at)
受信者のキーメトリック:
  • 'ak_latency'(受信→2xx)、 'processing_latency' (enqueue→done)
  • 'duplicates_total'、 'invalid_signature_total'、 'out_of_order_total'
SLOの例:

99.イベントの9%が最初のACK ≤ 60秒(28d)を受信します。

  • DLQ ≤ 0。全体の1%;DLQ再生≤ 24時間です。

11)タイミングおよびネットワーク休憩

タイムフィールドでUTCを使用します。NTPを同期します。
'occorded_at'を送信し、'delivered_at'を修正してラグを読み込みます。
長い休憩では、ネットワーク/エンドポイント→キューに蓄積し、成長を制限します(バックプレッシャー+クォータ)。

12)推薦された限界および衛生

サブスクリプションあたりのRPS(例: 50 RPS、バースト100)+並行(例:10).

マックス・マックス。ボディ:64-256 KB;詳細については「notification+URL」と署名をダウンロードしてください。
「ヘビ」のイベント名。case'または'dot。type'('order。')を作成しました。
受信者の書き込み操作の厳密なidempotency。

13)例: 送信者と受信者

13.1送信者(擬似コード)

python def send_event(event, attempt=0):
body = json. dumps(event)
sig = hmac_sha256_base64(body, secret)
headers = {
"X-Webhook-Id": event["id"],
"X-Webhook-Seq": str(event["sequence"]),
"X-Retry": str(attempt),
"X-Signature": f"sha256={sig}",
"Content-Type": "application/json"
}
res = http. post(endpoint, body, headers, timeout=10)
if 200 <= res. status < 300:
mark_delivered(event["id"])
elif res. status == 410:
deactivate_subscription()
else:
schedule_retry(event, attempt+1) # backoff + jitter, respect 429 Retry-After

13.2受信機(擬似コード)

python
@app. post("/webhooks")
def handle():
body  = request. data headers = request. headers assert verify_hmac(body, headers["X-Signature"], secret)
evt_id = headers["X-Webhook-Id"]
if dedup_store. exists(evt_id):
return, "" 204 enqueue_for_processing (body) # fast path. dedup_store put(evt_id, ttl=723600)
return, "" 202 # or 204

14)テストとカオスの実践

負の場合:無効な署名、429/5xx、タイムアウト、410、大きなペイロード。
行動:アウトオブオーダー、重複、1〜10分の遅延、24時間の休憩。
負荷:破烈10 ×;backpressureとDLQの持続性をチェックします。
契約:JSONスキーマ、必須の見出し、安定したイベントタイプ。

15)実装チェックリスト

  • 2xx=ACK、およびenqueue後のクイックリターン
  • 指数関数バックオフ+ジッタ、リスペクト'Retry-After'
  • 受信者IDempotencyとX-Webhook-Id (TTL ≥リトレイ)
  • HMAC署名、シークレット回転、オプションのmTLS
  • DLQ+リプレイAPI、監視およびアラート
  • 制限:タイムアウト、RPS、ボディサイズ
  • 注文:キーまたは'sequence'+「駐車場」によるパーティション"
  • ドキュメント:スキーマ、例、エラーコード、バージョン
  • カオステスト:遅延、重複、ネットワーク障害、長いリプレイ

16) ミニFAQ

私は常に200に答える必要がありますか?
すべての2xxは成功としてカウントされます。202/204は「キューに受け入れられる」ための通常の練習です。

リプレイは停止できますか?
はい、410応答および/または送信者のコンソール/API(購読解除)を介して。

大きなペイロードはどうですか?
「notification+secure URL」を送信し、ダウンロードリクエストに署名してTTLをインストールします。

順序を保障する方法か?
キー+'シーケンス'によるパーティション;不一致の場合-「駐車場」とリプレイ。

合計

信頼できるWebhookは明確なACK (2xx)の意味論、backoff+jitterの適度な繰り返し、厳密なidempotenceおよび重複除外、有能な保証(HMAC/mTLS)、キュー+DLQ+リプレイおよび透明な観察可能性です。契約を修正し、限界とメトリクスを入力し、定期的にカオスシナリオを実行します。統合は、最初の失敗時に「注入」を停止します。

Contact

お問い合わせ

ご質問やサポートが必要な場合はお気軽にご連絡ください。いつでもお手伝いします!

統合を開始

Email は 必須。Telegram または WhatsApp は 任意

お名前 任意
Email 任意
件名 任意
メッセージ 任意
Telegram 任意
@
Telegram を入力いただいた場合、Email に加えてそちらにもご連絡します。
WhatsApp 任意
形式:+国番号と電話番号(例:+81XXXXXXXXX)。

ボタンを押すことで、データ処理に同意したものとみなされます。