Webhooks: tekrarlar ve onaylar
1) Temel teslimat modeli
En az bir kez (varsayılan) - Etkinlik ≥1 kez teslim edilecektir. Tam bir kez garanti alıcı idempotency ile elde edilir.
Teşekkür (ACK): Alıcıdan sadece herhangi bir 2xx (genellikle 200/204) başarı anlamına gelir. Diğer her şey başarısızlık olarak yorumlanır ve tekrarlamaya yol açar.
Hızlı ACK: Tam iş işleminden sonra değil, olayı sırayla yerleştirdikten sonra 2xx'e yanıt verin.
2) Etkinlik formatı ve zorunlu başlıklar
Payload (örnek)
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
}
Gönderen Başlıkları
'X-Webhook-Id: evt_01HXYZ' - benzersiz olay kimliği (veri tekilleştirme için kullanılır).
'X-Webhook-Seq: 128374' - monoton sekans (abonelik/temaya göre).
'X-Signature: sha256 = <base64 (hmac_sha256 (body, secret))>' - HMAC- подпись.
'X-Retry: 0,1,2... 'deneme sayısıdır.
'X-Webhook-Version: 1' - sözleşme sürümü.
(Isteğe bağlı) 'Traceparent' - iz korelasyonu.
Alıcıdan yanıt
2xx - başarıyla kabul edildi (bu'id 'için başka tekrar olmayacak).
410 Gitti - uç nokta silindi/etkin değil - gönderen yeniden denemeleri sonlandırır ve aboneliği devre dışı bırakır.
429/5xx/timeout - gönderen, yeniden ödeme politikasına göre tekrar eder.
3) Politikayı yeniden dener
Önerilen geri alma merdiveni (+ jitter)
'1s, 3s, 10s, 30s, 2m, 10m, 30m, 2h, 6h, 24h' (sınırdan sonra durun, örneğin 48-72 saat).
Kurallar:- "Sürü etkisi'nden kaçınmak için üstel geri dönüş + rastgele titreme (± %20-30).
- Geçici arızalar için hata sayısı (örneğin, 5xx veya ağ zaman aşımı durumunda yeniden deneme).
- Saygı 429: minimum'min (Retry-After header, next backoff window) "ayarını yapın.
Zaman aşımları ve boyutları
Bağlantı zaman aşımı ≤ 3-5 saniye; Toplam yanıt süresi ≤ 10 saniye
Sözleşme altındaki gövdenin boyutu (örneğin, ≤ 256 KB), aksi takdirde 413 - "gruplama" veya "URL'yi çekme" mantığı.
4) Idempotency ve veri tekilleştirme
Idempotent uygulaması: Aynı'id'in tekrarlarının işlenmesi aynı sonucu döndürmeli ve durumu tekrar değiştirmemelidir.
Alıcı tarafında Dedup depolama: TTL processed_at retray pencereleri ile '(X-Webhook-Id, ≥, sağlama toplamı)' deposu (24-72 saat).
Kompozisyon anahtarı: eğer birkaç konu varsa - '(subscription_id, event_id)'.
5) Sipariş ve "tam olarak bir kez etkileri"
Dağıtılmış sistemlerde sıkı düzeni garanti etmek zordur. Kullan:- Anahtarla bölme: aynı mantıksal küme (örneğin, 'order _ id') her zaman bir "kanal" içinde teslim edilir.
- Sekans: Eski 'X-Webhook-Seq'ile olayları reddedin ve eksik olanlar gelmeden önce onları "park alanına" koyun.
- Uygulanan işlemlerin günlüğü (giden kutusu/gelen kutusu deseni),
- Veritabanında 'event _ id'ile işlemsel upsert,
- Karmaşık süreçler için destanlar/tazminatlar.
6) Durum kodlarına göre hata çözümü (Tablo)
7) Kanal güvenliği
Her mesajın HMAC imzası; Alıcıyı "zaman penceresi'ile kontrol edin (mitm ve tekrarlama saldırıları).
Hassas alanlar için mTLS (LCC/ödemeler).
Giden adreslerin IP allowlisti, TLS 1. 2 +, HSTS.
PII minimizasyonu: gereksiz kişisel verileri göndermeyin; Kayıtlarda kılık değiştiriyor.
Sırların döndürülmesi: geçerli iki anahtar (etkin/sonraki) ve geçerli olanı belirtmek için 'X-Key-Id' başlığı.
8) Kuyruklar, DLQ'lar ve Tekrarları
Olaylar, gönderen tarafındaki çıkış kuyruğuna/günlüğüne yazılmalıdır (güvenilir yeniden oynatma için).
Maksimum geri alma sayısı aşılırsa, olay nedeni ile DLQ'ya (Dead Letter Queue) gider.
Yeniden Oynatma API'si (alıcı/operatör için): RPS kısıtlaması ve ek imza/yetkilendirme ile'id'/zaman aralığı/konu ile yeniden gönderin.
POST /v1/webhooks/replay
{ "subscription_id": "sub_123", "from": "2025-11-03T00:00:00Z", "to": "2025-11-03T12:00:00Z" }
→ 202 Accepted
9) Sözleşme ve sürüm
Olayın ('schema _ version' alanı) ve aktarımın ('X-Webhook-Version') sürümü.
Alanları yalnızca isteğe bağlı olarak ekleyin; silme üzerinde - küçük geçiş ve geçiş dönemi (çift yazma).
Belge olay türleri, örnekler, şemalar (JSON Şemaları), hata kodları.
10) Gözlemlenebilirlik ve SLO
Gönderici Anahtar Metrikleri:- 'teslim _ başarı _ oranı' (2xx/tüm girişimleri),'ilk _ girişimi _ başarı _ oranı '
- 'retries _ total', 'max _ retry _ age _ seconds', 'dlq _ count'
- 'latency _ p50/p95' (occurred_at ack_received_at)
- 'ack _ latency' (receive> 2xx), 'processing _ latency' (enqueue _ done)
- 'duplicates _ total', 'invalid _ signature _ total', 'out _ of _ order _ total'
99. Etkinliklerin %9'u 60 saniye (28d) ≤ ilk ACK'yi alır.
- DLQ ≤ 0. Toplamın %1'i; 24 saat ≤ DLQ tekrarı.
11) Zamanlama ve ağ sonları
Zaman alanlarında UTC kullanın; NTP'yi senkronize et.
Gecikmeyi okumak için 'incidented _ at' yazıp 'delivered _ at' düzeltmesini gönderin.
Uzun molalarla, ağ/uç nokta - kuyrukta birikir, büyümeyi sınırlar (geri basınç + kotalar).
12) Önerilen sınırlar ve hijyen
Abonelik başına RPS (örn. 50 RPS, burst 100) + eşzamanlılık (örn. 10).
Max. gövde: 64-256 KB; Daha fazlası için - "bildirim + URL've indirme imzası.
Etkinlik isimleri yılan. case'ya da 'nokta. type '(' sipariş. yaratıldı ').
Alıcının yazma işlemlerinin sıkı idempotensi.
13) Örnekler: Gönderen ve Alıcı
13. 1 Gönderici (sözde kod)
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 Alıcı (pseudocode)
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) Test ve kaos uygulamaları
Olumsuz durumlar: geçersiz imza, 429/5xx, zaman aşımı, 410, büyük yükler.
Davranışsal: sıra dışı, kopyalar, 1-10 dakikalık gecikmeler, 24 saat ara.
Yük: patlama 10 ×; Geri basınç ve DLQ kalıcılığını kontrol edin.
Sözleşmeler: JSON Schema, zorunlu başlıklar, kararlı olay türleri.
15) Uygulama kontrol listesi
- 2xx = ACK ve sorudan sonra hızlı dönüş
- Üstel geri dönüş + jitter, saygı 'Retry-After'
- Alıcı IDempotency ve X-Webhook-Id (TTL ≥ Retray)
- HMAC imzaları, gizli rotasyon, isteğe bağlı mTLS
- DLQ + Replay API, İzleme ve Uyarılar
- Sınırları: Zaman aşımları, RPS, Vücut Boyutu
- Sipariş: anahtarla veya 'sıra'ile bölme + "otopark"
- Belgeler: şemalar, örnekler, hata kodları, sürümler
- Kaos testleri: gecikmeler, kopyalar, ağ arızası, uzun tekrar oynatma
16) Mini-SSS
Her zaman 200'e cevap vermem gerekiyor mu?
Herhangi bir 2xx başarı sayılır. 202/204 "kuyruğa kabul" için normal bir uygulamadır.
Tekrarlar durdurulabilir mi?
Evet, 410 yanıtı ve/veya gönderenin konsolu/API'si (abonelikten çıkma) aracılığıyla.
Peki ya büyük yükler?
Bir "bildirim + güvenli URL" gönderin, indirme isteğini imzalayın ve TTL'yi yükleyin.
Sipariş nasıl sağlanır?
Tuşa göre bölme + 'sıra'; Tutarsızlık durumunda - "otopark've tekrar oynatma.
Toplam
Güvenilir webhook'lar net ACK (2xx) semantiği, backoff + jitter ile makul tekrarlar, sıkı idempotence ve veri tekilleştirme, yetkin güvenlik (HMAC/mTLS), kuyruklar + DLQ + tekrarları ve şeffaf gözlemlenebilirliktir. Sözleşmeyi düzeltin, limitleri ve metrikleri girin, düzenli olarak kaos senaryoları çalıştırın - ve entegrasyonlarınız ilk başarısızlıklarda "dökülmeyi" durduracaktır.