Webhooks va voqealarning idempotentligi
TL; DR
Yaxshi vebxuk - bu imzolangan (HMAC/mTLS), xulosa chiqariladigan va idempotent hodisa bo’lib, u at-least-once modeli bo’yicha eksponensial backoff va qabul qiluvchidan duplikatsiya bilan yetkazib beriladi. Konvertni (’event _ id’,’type’,’ts’,’version’,’attempt’,’signature’), vaqt oynasini (≤ 5 daqiqa), javob kodlarini, retraylarni, DLQ va status-endpint haqida kelishib oling.
1) Yetkazib berish roli va modeli
Joʻnatuvchi (siz/provayder): voqeani shakllantiradi, imzo chekadi, 2xx gacha yetkazishga harakat qiladi, 3xx/4xx/5xx da retrayt (aniq «qabul qilmang» dan tashqari), DLQ yuritadi, replay API beradi.
Qabul qiluvchi (sherik/xizmatingiz): imzoni/vaqtinchalik oynani tekshiradi, dedupni va idempotentni qayta ishlaydi, toʻgʻri kod bilan javob beradi ,/status va/ack replay’ni’event _ id’bilan taqdim etadi.
Kafolatlar: at-least-once. Oluvchi dublikatlarni qayta ishlashi va tartibni o’zgartirishi kerak.
2) Hodisa konvertlari (envelope)
json
{
"event_id": "01HF7H9J9Q3E7DYT5Y6K3ZFD6M",
"type": "payout.processed",
"version": "2025-01-01",
"ts": "2025-11-03T12:34:56.789Z",
"attempt": 1,
"producer": "payments",
"tenant": "acme",
"data": {
"payout_id": "p_123",
"status": "processed",
"amount_minor": 10000,
"currency": "EUR"
}
}
Majburiy maydonlar:’event _ id’,’type’,’version’,’ts’,’attempt’.
Evolyutsiya qoidalari: dalalarni qo’shing; turlarni olib tashlash/almashtirish - faqat yangi’version’bilan.
3) Xavfsizlik: imzolar va bog’lash
3. 1 HMAC imzosi (andoza boʻyicha tavsiya etiladi)
Sarlavhalar:
X-Signature: v1=base64(hmac_sha256(<secret>, <canonical>))
X-Timestamp: 2025-11-03T12:34:56Z
X-Event-Id: 01HF7...
Kanonik satr:
<timestamp>\n<method>\n<path>\n<sha256(body)>
Oluvchida tekshirish:
- abs(now − `X-Timestamp`) ≤ 300s
- ’X-Event-Id’ avval ishlanmagan (dedup)
- ’X-Signature’ mos keladi (taym-xavfsiz taqqoslash bilan)
3. 2 Qo’shimcha chora-tadbirlar
mTLS yuqori sezgir vebxuklar uchun.
IP/ASN allow-list.
Agar vebxuk orqaga chaqirishni boshlasa, sender-constrained uchun DPoP (ixtiyoriy).
4) Idempotentlik va deduplikatsiya
4. 1 Voqeaning idempotentligi
Bir xil’event _ id’boʻlgan hodisa holatini qayta oʻzgartirmasligi kerak. Oluvchi:- «event _ id» ni idempotent kishida (KV/Redis/DB) TTLda 24-72 soat ≥ saqlaydi;
- qayta berish uchun qayta ishlash natijasini (muvaffaqiyat/xato, artefaktlar) saqlab qoladi.
4. 2 Jamoalarning idempotentligi (orqaga chaqiruvlar)
Agar vebxuk mijozni APIni tortib olishga majbur qilsa (masalan, «payout tasdiqla»), «Idempotency-Key» dan oʻsha REST chaqiruvida foydalaning, natijani xizmat tomonida saqlang (exactly-once outcome).
KV-model (minimal):
key: idempotency:event:01HF7...
val: { status: "ok", processed_at: "...", handler_version: "..." }
TTL: 3d
5) Retrai va backoff
Tavsiya etilayotgan jadval (jitter bilan eksponensial):- ’5s, 15s, 30s, 1m, 2m, 5m, 10m, 30m, 1h, 3h, 6h, 12h, 24h’ (keyingi o’rinlarda N kungacha har kuni)
- 2xx - muvaffaqiyat, retrajni to’xtatish.
- ’400/ 401/403/404/422’ - imzo/formati ok (mijoz xatosi) bo’lsa, retraim emas.
- ’429’ -’Retry-After’yoki backoff bo’yicha retraim.
- 5xx/tarmoq - retraim.
Joʻnatuvchining sarlavhalari: «User-Agent», «X-Webhook-Producer», «X-Attempt».
6) Oluvchi tomonida ishlov berish
Psevdopaypline:pseudo verify_signature()
if abs(now - X-Timestamp) > 300s: return 401
if seen(event_id):
return 200 // идемпотентный ответ
begin transaction if seen(event_id): commit; return 200 handle(data) // доменная логика mark_seen(event_id) // запись в KV/DB commit return 200
Tranzaksiyalilik: muvaffaqiyatsiz tugaganida ikki marta ishlov berilmasligi uchun «seen» belgisi operatsiya effekti bilan (yoki natija qayd etilgandan keyin) atomlashtirilgan holda qoʻyilishi kerak.
7) Tartib va snapshotlar kafolatlari
Tartib kafolatlanmagan. Dolzarbligini tekshirish uchun’ts’va’seq ’/’ version’domenlaridan foydalaning.
Uzoq lag/yo’qotishlar uchun - jo’natuvchidan/replay va qabul qiluvchidan/resync qo’shing (vaqt oynasi/ID bo’yicha snapshot va delta olish).
8) Maqom, replay va DLQ
8. 1 Joʻnatuvchining endpointlari
’POST/webhooks/replay’ -’event _ id’roʻyxati yoki vaqt oynasi boʻyicha.
’GET/webhooks/events/: id’ - dastlabki paket va urinishlar tarixini koʻrsatish.
DLQ: «o’lik» voqealar (retray limiti tugagan) → alohida ombor, alertlar.
8. 2 Oluvchining endpointlari
`GET /webhooks/status/:event_id` — `seen=true/false`, `processed_at`, `handler_version`.
’POST/webhooks/ack’ - DLQ dan qo’lda ishlov berilganligini tasdiqlash.
9) Xato kontraktlari (oluvchining javobi)
http
HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json
Retry-After: 120
X-Trace-Id: 4e3f...
{
"error": "invalid_state",
"error_description": "payout not found",
"trace_id": "4e3f..."
}
Tavsiyalar: har doim aniq kodni va iloji boʻlsa,’Retry-After’ni qaytaring. Xavfsizlik tafsilotlarini qaytarmang.
10) Monitoring va SLO
Metriklar (joʻnatuvchi):- delivery p50/p95, success rate, retrai/voqea, drop-rate DLQ, share 2xx/4xx/5xx, kechikish oynasi 2xx gacha.
- verify fail rate (imzo/vaqt), dup-rate, latency handler p95, 5xx.
- Yetkazib berish: 99 ≥. Voqealarning 9% 2xx <3 c p95 oladi (birinchi muvaffaqiyatli urinishdan keyin).
- Kriptoproverlash: imzoni validatsiya qilish ≤ 2-5 ms p95.
- Dedup: 0 ta takroriy effektlar (domen darajasida exactly-once outcome).
11) Ma’lumotlarning xavfsizligi va maxfiyligi
Vebxuk tanasida PAN/PII uzatmang; avtorizatsiya qilingan API tafsilotlari uchun identifikatorlardan va keyingi pulldan foydalaning.
Loglardagi sezgir maydonlarni yashiring; hodisalarni faqat TTL bilan minimal darajada saqlang.
DLQ va replay omborlarini shifrlang.
12) Versiyalash va muvofiqlik
’version’ (konvertda) va ’/webhooks/v1/payments’.
Yangi maydonlar - ixtiyoriy; olib tashlash - faqat «Sunset» davridan keyin.
O’zgarishlarni machine-readable changelog’da hujjatlashtiring.
13) Test-keyslar (UAT chek-varaqasi)
- Bir xil’event _ id’→ bitta effekt va’200’ni dublikatlarga qayta yetkazib berish.
- Imzo: haqiqiy kalit, notoʻgʻri kalit, eski kalit (rotatsiya), «X-Timestamp» derazadan tashqarida.
- Backoff: qabul qiluvchi’429’s’Retry-After’→ to’g’ri pauza beradi.
- Tartib:’... processed’voqealari oldinroq keladi’... created’→ toʻgʻri ishlov berish/kutish.
- Qabul qiluvchida va’mark _ seen’effekti orasidagi BD muvaffaqiyatsiz tugadi → atom/takrorlash.
- DLQ va qo’lda replay → muvaffaqiyatli etkazib berish.
- Ommaviy «bo’ron» (provayder qutilarni yuboradi) → yo’qotishsiz, limitlar juda muhim bo’lmaydi.
14) Mini-snippetlar
Jo’natuvchining imzosi (psevdo):pseudo body = json(event)
canonical = ts + "\n" + "POST" + "\n" + path + "\n" + sha256(body)
sig = base64(hmac_sha256(secret, canonical))
headers = {"X-Timestamp": ts, "X-Event-Id": event.event_id, "X-Signature": "v1="+sig}
POST(url, body, headers)
Oluvchini tekshirish va uning dedupi (psevdo):
pseudo assert abs(now - X-Timestamp) <= 300 assert timingSafeEqual(hmac(secret, canonical), sig)
if kv.exists("idemp:"+event_id): return 200
begin tx if kv.exists("idemp:"+event_id): commit; return 200 handle(event.data) // доменная логика kv.set("idemp:"+event_id, "ok", ttl=259200)
commit return 200
15) Tez-tez xatolar
Dedup yoʻq → takroriy effektlar (ikki marta refandlar/payautlar).
Taymshtampsiz imzo → replay uchun zaiflik.
Barcha sheriklar uchun bitta HMAC sirini saqlash.
Natijani aniqlashdan oldin javoblar’200’→ kresh paytida hodisalarni yo’qotish.
Javob/logida xavfsizlik detallarini «yuvish».
DLQ/replay yo’qligi - hodisalarni hal qilib bo’lmaydi.
16) Joriy etish shpargalkasi
Xavfsizlik: HMAC v1 +’X-Timestamp’+’X-Event-Id’, deraza ≤ 5 daqiqa; mTLS/IP allow-list kerak bo’lganda.
Конверт: `event_id`, `type`, `version`, `ts`, `attempt`, `data`.
Yetkazib berish: at-least-once, jitter bilan backoff,’Retry-After’, DLQ + replay API.
Idempotentlik: KV-kesh 24-72 soat, +’mark _ seen’effektining atomik fiksatsiyasi.
Kuzatilishi: yetkazib berish metrikasi, imzolar, dublikatlar; ’trace _ id’ izlanishi.
Hujjatlar: versiya, javob kodlari, misollar, UAT-chek varaqasi.
Xulosa
Mustahkam vebxuklar uchta kitga quriladi: imzolangan konvert, at-least-once yetkazib berish va idempotent ishlov berish. Shartnomani rasmiylashtiring, HMAC/mTLS va vaqt oynasini yoqing, + DLQ retraylarini va repleylarini amalga oshiring, idempotent belgilarini saqlang va ta’sirlarni atomlarda qayd qiling. O’shanda voqealar tarmoqdagi nosozliklar, yukning cho’qqilari va kamdan-kam uchraydigan «taqdirning dublikatlari» bilan ham ishonchli bo’lib qoladi.