Webhooks: takrorlash va kvitatsiya
1) Yetkazib berishning bazaviy modeli
At-least-once (andoza): hodisa 1 marta ≥. Kafolatlarga qabul qiluvchining idempotentligi bilan bir marta erishiladi.
Kvitatsiya (ACK): faqat oluvchidan har qanday 2xx (odatda 200/204) muvaffaqiyat demakdir. Qolganlari rad etish deb talqin qilinadi va takrorlanishga olib keladi.
Tezkor ACK: 2xx javob bering tadbirni o’z navbatida joylashtirgandan so’ng, to’liq ishlangandan so’ng emas.
2) Voqealar formati va majburiy sarlavhalar
Foydali yuk (misol)
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
}
Joʻnatuvchining sarlavhalari
’X-Webhook-Id: evt_01HXYZ' - voqeaning oʻziga xos ID-si.
’X-Webhook-Seq: 128374’ - monoton ketma-ketlik (obuna/mavzu bo’yicha).
`X-Signature: sha256=<base64(hmac_sha256(body, secret))>` — HMAC-подпись.
’X-Retry: 0,1,2...’ - urinish raqami.
’X-Webhook-Version: 1’ - shartnomani versiyalash.
(ixtiyoriy)’Traceparent’- trassalarning korrelyatsiyasi.
Oluvchining javobi
2xx - muvaffaqiyatli qabul qilindi (bundan keyin bu’id’bo’yicha takrorlash bo’lmaydi).
410 Gone - endpoint oʻchirilgan/aktiv emas → joʻnatuvchi takrorlashni toʻxtatadi va obunani oʻchiradi.
429/5xx/taymaut - jo’natuvchi retraj siyosati bo’yicha takrorlaydi.
3) Takrorlash siyosati (retries)
Tavsiya etilgan backoff (+ jitter)
’1s, 3s, 10s, 30s, 2m, 10m, 30m, 2h, 6h, 24h’ (limitdan keyin to’xtaymiz, masalan, 48-72 soat).
Qoidalar:- «Poda effektidan» qochish uchun eksponensial backoff + tasodifiy jitter (20-30% ±).
- Vaqtinchalik xatolar kvorumi (masalan, agar 5xx yoki tarmoq taymaut boʻlsa takrorlash).
- Respect 429: minimum’min’(Retry-After sarlavhasi, keyingi backoff oynasi)’.
Taymautlar va o’lchamlar
Ulanish vaqti ≤ 3-5 sek; javobning umumiy vaqti ≤ 10 sek.
Tana o’lchami kontrakt bo’yicha (masalan, 256 KB ≤), aks holda 413 → mantiq «chunking» yoki «pull URL».
4) Idempotentlik va deduplikatsiya
Idempotent qo’llash: o’sha’id’ning takrorlanishiga ishlov berish xuddi shu natijani qaytarishi va holatini qayta o’zgartirmasligi kerak.
Qabul qiluvchi tomonidagi dedup-saqlash joyi:’(X-Webhook-Id, processed_at, checksum)’bilan TTL ≥ retray oynalarini saqlash (24-72 soat).
Kompozitsiya kaliti: agar bir nechta topiklar boʻlsa →’(subscription_id, event_id)’.
5) Tartib va «exactly-once effekt»
Taqsimlangan tizimlarda qatʼiy tartibni kafolatlash qiyin. Foydalaning:- Partition by key: bir xil mantiqiy toʻplam (masalan,’order _ id’) har doim bitta yetkazib berish kanalida.
- Sequence: eski’X-Webhook-Seq’bilan voqealarni rad eting va yetib kelmaguncha ularni «parking lot» ga qo’ying.
- qo’llanilgan operatsiyalar jurnali (outbox/inbox pattern),
- DBga’event _ id’bo’yicha tranzaksion upsert,
- murakkab jarayonlar uchun saga/kompensatsiya.
6) Status-kodlar bo’yicha xatolarni hal etish (jadval)
7) Kanal xavfsizligi
Har bir xabarning HMAC imzosi; qabul qilgichda «vaqt oynasi» (mitm va replay-hujumlar) bilan tekshirish.
sezgir domenlar uchun mTLS (KTS/to’lovlar).
IP allowlist chiquvchi manzillar, TLS 1. 2+, HSTS.
PII-minimallashtirish: ortiqcha shaxsiy ma’lumotlarni yubormang; daftarlarda yashiring.
Sirlarni almashtirish: amaldagi ikkita kalit (active/next) va joriy kalit uchun «X-Key-Id» sarlavhasi.
8) Navbatlar, DLQ va repley
Hodisalar joʻnatuvchi tomonidan chiqish navbatida/jurnalda yozilishi shart (ishonchli replay uchun).
Agar retrayning maksimal miqdori oshsa, hodisa sababi bilan DLQ (Dead Letter Queue) ga boradi.
Replay API (oluvchi/operator uchun): RPS cheklangan va qo’shimcha imzo/avtorizatsiya qilingan’id ’/vaqt oralig’i/mavzu bo’yicha qayta jo’natish.
POST /v1/webhooks/replay
{ "subscription_id": "sub_123", "from": "2025-11-03T00:00:00Z", "to": "2025-11-03T12:00:00Z" }
→ 202 Accepted
9) Kontrakt va versiya
Hodisani (’schema _ version’) va transportni (’X-Webhook-Version’) versiya qiling.
Maydonlarni faqat ixtiyoriy deb qoʻshing; olib tashlanganda - minor migratsiya va o’tish davri (dual-write).
Hodisa turlarini, misollarni, sxemalarni (JSON Schema), xato kodlarini hujjatlashtiring.
10) Kuzatuv va SLO
Joʻnatuvchining asosiy metrikasi:- ’delivery _ success _ rate’ (2xx/barcha urinishlar),’first _ attempt _ success _ rate ’
- `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. Voqealarning 9% birinchi ACK ≤ 60 sek (28d) oladi.
- DLQ ≤ 0. umumiy sonning 1 foizi; DLQ repley ≤ 24 soat
11) Tayming va tarmoqning uzilishi
UTC dan vaqt maydonlarida foydalaning; NTPni sinxronlashtiring.
’occurred _ at’ joʻnating va’delivered _ at’joʻnating.
Uzoq vaqt davomida/endpoint → tarmog’i uzilganda, navbatda to’planib, o’sishni cheklang (backpressure + kvotalar).
12) Tavsiya etilgan limitlar va gigiyena
Obuna uchun RPS (masalan, 50 RPS, burst 100) + parallelizm (masalan, 10).
Maks. tanasi: 64-256 KB; ko’proq uchun - «notification + URL» va yuklab olish uchun imzo.
’snake’ dagi voqealar nomlari. case’ili’dot. type` (`order. created`).
Qabul qilgichning write-operatsiyalarining qat’iy idempotentligi.
13) Misollar: jo’natuvchi va oluvchi
13. 1 Jo’natuvchi (soxta hujjat)
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 Oluvchi (soxta hujjat)
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 va xaos-amaliyot
Salbiy holatlar: nolid imzo, 429/5xx, taymaut, 410, katta payload’lar.
Xulq-atvor: out-of-order, dublikatlar, kechikishlar 1-10 daqiqa, tanaffus 24 soat.
Yuklama: burst 10 ×; backpressure va DLQ barqarorligini tekshiring.
Shartnomalar: JSON Schema, majburiy sarlavhalar, barqaror voqealar turlari.
15) Joriy etish chek-varaqasi
- 2xx = ACK va enqueue dan keyin tez qaytish
- Eksponensial backoff + jitter, hurmat’Retry-After ’
- Qabul qiluvchining idempotentligi va «X-Webhook-Id» bo’yicha dedup (TTL ≥ retray)
- HMAC imzolari, sirlarni almashtirish, optional mTLS
- DLQ + Replay API, monitoring va alertlar
- Cheklovlar: taymautlar, RPS, tana o’lchami
- Tartib: partition by key yoki’sequence’+ «parking lot»
- Hujjatlar: sxemalar, misollar, xato kodlari, versiyalar
- Xaos-testlar: kechikishlar, dubllar, tarmoqning ishdan chiqishi, uzoq vaqt replay
16) Mini-FAQ
Har doim 200 ga javob berish kerakmi?
Har qanday 2xx muvaffaqiyat deb hisoblanadi. 202/204 - «navbatga qabul qilingan» uchun normal amaliyot.
Takrorlashni toʻxtatish mumkinmi?
Ha, 410 javob va/yoki joʻnatuvchining konsoli/API orqali (obunani oʻchirish).
Katta payloadlar haqida nima deyish mumkin?
«Bildirishnoma + secure URL» ni yuboring, yozib olish soʻrovini imzolang va TTLni oʻrnating.
Tartib-intizomni qanday taʼminlash mumkin?
Partition by key + `sequence`; farqlanganda - «parking lot» va qayta o’ynash.
Jami
Ishonchli vebxuklar - bu ACK (2xx) ning aniq semantikasi, backoff + jitter bilan oqilona takrorlash, qatʼiy idempotentlik va deduplikatsiya, savodli xavfsizlik (HMAC/mTLS), navbatlar + DLQ + replelar va shaffof kuzatish. Shartnomani tuzating, limitlar va ko’rsatkichlarni kiriting, muntazam ravishda xaos-stsenariylarni haydang - va birinchi nosozliklarda sizning integratsiyalaringiz to’xtaydi.