Webhooks: қайталау және квитирлеу
1) Жеткізудің базалық моделі
At-least-once (әдепкі): оқиға 1 реттен ≥ жеткізіледі. Кепілдіктерге қабылдағыштың біркелкілігімен біркелкі қол жеткізіледі.
Квитирлеу (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 - endpoint жойылған/белсенді емес → жіберуші қайталауды тоқтатады және жазылымды өшіреді.
429/5хх/таймаут - жөнелтуші ретрайлер саясаты бойынша қайталайды.
3) Қайталау саясаты (retries)
Ұсынылған backoff сатысы (+ jitter)
'1s, 3s, 10s, 30s, 2m, 10m, 30m, 2h, 6h, 24h' (лимиттен кейін тоқтаймыз, мысалы 48-72 сағат).
Ережелер:- Экспоненциалды backoff + кездейсоқ jitter (± 20-30%) «табын әсерін» болдырмау үшін.
- Уақытша жаңылыс үшін қателер кворумы (мысалы, егер 5xx немесе желі таймауты болса қайталау).
- Respect 429: минимум 'min' қойыңыз (Retry-After тақырыбы, келесі backoff терезесі).
Таймауттар мен өлшемдер
Қосылу уақыты ≤ 3-5 сек; жауаптың жалпы уақыты ≤ 10 сек.
Келісімшарт бойынша дененің өлшемі (мысалы, ≤ 256 KB), әйтпесе 413 → «chunking» немесе «pull URL» логикасы.
4) Ұқсастық және дедупликация
Іспеттес қолдану: сол 'id' қайталауларын өңдеу сол нәтижені қайтаруы және күйін қайта өзгертпеуі тиіс.
Алушы жағындағы дедуп-сақтау орны: '(X-Webhook-Id, processed_at, checksum)' TTL ≥ ретрайлер терезелерімен (24-72 сағ) сақтау.
Композициялық кілт: бірнеше топиктер болса → '(subscription_id, event_id)'.
5) Тәртібі және «exactly-once әсерлері»
Бөлінген жүйелерде қатаң тәртіпке кепілдік беру қиын. Пайдаланыңыз:- Partition by key: бірдей логикалық жиын (мысалы, 'order _ id') әрқашан бір жеткізу «арнасына».
- Sequence: ескі 'X-Webhook-Seq' оқиғаларын қабылдамаңыз және жетіспеушілер келгенге дейін оларды «parking lot» -ке қойыңыз.
- қолданылған операциялар журналы (outbox/inbox pattern),
- «event _ id» бойынша транзакциялық upsert
- күрделі процестер үшін сағалар/өтемақылар.
6) Статус-кодтар бойынша қателерді шешу (кесте)
7) Арна қауіпсіздігі
Әрбір хабарламаның HMAC қолы; «уақыт терезесі» бар қабылдағышта тексеру (mitm және replay-шабуылдар).
сезімтал домендер үшін mTLS (АКЖ/төлемдер).
IP allowlist шығыс мекенжайлары, TLS 1. 2+, HSTS.
PII-минимизация: артық жеке деректерді жібермеңіз; логтарда жасырыңыз.
Құпияларды ротациялау: екі қолданыстағы кілт (active/next) және ағымдағы кілтті көрсету үшін 'X-Key-Id' тақырыбы.
8) Кезектер, DLQ және реплика
Оқиғалар міндетті түрде шығу кезегіне/журналға жіберуші жағына жазылады (сенімді реплей үшін).
Ретрациялардың максимумы артқанда - оқиға DLQ (Dead Letter Queue) себебімен кетеді.
Replay API (алушы/оператор үшін): RPS шектеулерімен және қосымша қолтаңбамен/авторизациямен 'id '/уақыт ауқымы/тақырып бойынша қайта жіберу.
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') нұсқалаңыз.
Өрістерді тек қосымша ретінде қосыңыз; алып тастау кезінде - минорлы көші-қон және өтпелі кезең (dual-write).
Оқиға түрлерін, мысалдарды, схемаларды (JSON Schema), қате кодтарын құжаттаңыз.
10) Бақылау және SLO
Жіберушінің негізгі өлшемдері:- 'delivery _ success _ rate' (2хх/барлық әрекеттер), '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. Оқиғалардың 9% бірінші ACK ≤ 60 секунд (28d) алады.
- DLQ ≤ 0. жалпы санынан 1%; DLQ репликасы ≤ 24 сағ.
11) Тайминг және желінің үзілуі
Уақыт өрістерінде UTC қолданыңыз; NTP үндестіріңіз.
'occurred _ at' дегенді жіберіп, 'delivered _ at' дегенді белгілеңіз.
Ұзақ үзілістерде/endpoint → желісін кезекке қойыңыз, өсуді шектеңіз (backpressure + квоталар).
12) Ұсынылған лимиттер және гигиена
Жазылуға арналған RPS (мысалы, 50 RPS, burst 100) + параллелизм (мысалы, 10).
Макс. денесі: 64-256 KB; көбірек үшін - «notification + URL» және жүктеуге қолтаңба.
'snake' ішіндегі оқиғалар атаулары. case 'немесе' dot. type` (`order. created`).
Қабылдағыштың write-операцияларының қатаң сәйкестігі.
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, үлкен payload '.
Мінез-құлық: out-of-order, телнұсқалар, кідірістер 1-10 минут, үзіліс 24 сағат.
Жүктеме: burst 10 ×; backpressure және DLQ тұрақтылығын тексеріңіз.
Келісімшарттар: JSON Schema, міндетті тақырыптар, оқиғалардың тұрақты түрлері.
15) Енгізу чек-парағы
- 2xx = ACK, және enqueue кейін жылдам қайтару
- Экспоненциалды backoff + jitter, құрмет 'Retry-After'
- Қабылдағыштың сәйкестігі және «X-Webhook-Id» дедупы (TTL ≥ ретра)
- Қолтаңбалар HMAC, құпияларды ротациялау, optional mTLS
- DLQ + Replay API, мониторинг және тәуекелдер
- Шектеулер: таймауттар, RPS, дене өлшемі
- Тәртібі: partition by key немесе 'sequence' + «parking lot»
- Құжаттама: схемалар, мысалдар, қате кодтары, нұсқалар
- Хаос-тесттер: кідірістер, қосарланған, желі істен шығуы, ұзақ replay
16) Шағын FAQ
Әрқашан 200 деп жауап беру керек пе?
Кез келген 2xx табыс ретінде есептеледі. 202/204 - «кезекке тұру» үшін қалыпты тәжірибе.
Қайталауды тоқтатуға бола ма?
Иә, 410 жауабымен және/немесе консоль/жіберушінің API арқылы (жазылымды өшіру).
Үлкен payload 'термен не істеу керек?
«Хабарлама + secure URL» жіберіп, жүктеу сұрауына қол қойып, TTL орнатыңыз.
Тәртіпті қалай қамтамасыз етуге болады?
Partition by key + `sequence`; айырмашылық болған кезде - «parking lot» және қайта ойнау.
Жиынтығы
Сенімді вебхактар - бұл ACK (2xx) айқын семантикасы, backoff + jitter-мен ақылға қонымды қайталаулар, қатаң идемпотенттік және дедупликация, сауатты қауіпсіздік (HMAC/mTLS), кезектер + DLQ + репликалар және мөлдір бақылау. Келісімшартты белгілеңіз, лимиттер мен өлшемдерді енгізіңіз, хаос сценарийлерін ұдайы қуып шығыңыз - сонда сіздің интеграцияларыңыз алғашқы сәтсіздіктерде «төгілуді» тоқтатады.