Webhooks: кайталоо жана кабыл алуу
1) Базалык жеткирүү модели
At-least-once (демейки): окуя ≥ 1 жолу жеткирилет. Кепилдиктер бир-бир жолу кабыл алуучунун демпотенттүүлүгү менен жетишилет.
Квитирлөө (ACK): алуучудан каалаган 2xx (адатта 200/204) гана ийгиликти билдирет. Калганынын баары баш тартуу катары чечмеленип, кайталанууга алып келет.
Fast 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 ≥ терезе retrains (24-72 саат).
Композициялык ачкыч: бир нече топик болсо → '(subscription_id, event_id)'.
5) тартиби жана "exactly-once таасирлери"
Бөлүштүрүлгөн системаларда катуу тартипке кепилдик берүү кыйын. Колдонуу:- Partition by key: бир эле логикалык көптүк (мисалы, 'order _ id') ар дайым бир "канал" жеткирүү.
- Sequence: эски 'X-Webhook-Seq' менен окуяларды четке кагып, жоктор келгенге чейин аларды "parking lot".
- колдонулган операциялар журналы (outbox/inbox pattern),
- транзакциялык upsert 'event _ id' боюнча DB,
- татаал процесстер үчүн дастан/компенсация.
6) Статус коддору боюнча каталарды чечүү (таблица)
7) Канал коопсуздугу
Ар бир билдирүүнүн HMAC кол тамгасы; "убакыт терезе" (mitm жана replay-чабуул) менен кабылдагычта текшерүү.
сезгич домендер үчүн mTLS (KUS/төлөмдөр).
IP allowlist чыгыш даректери, TLS 1. 2+, HSTS.
PII-минималдаштыруу: кошумча жеке маалыматтарды жибербеңиз; жашырып.
Сырларды айлантуу: эки активдүү ачкыч (active/next) жана 'X-Key-Id' аталышы учурдагы ачкычты көрсөтүү үчүн.
8) кезек, DLQ жана реплика
Иш-чаралар сөзсүз жөнөтүүчү тарапта чыгуу кезегине/журналга жазылат (ишенимдүү реплика үчүн).
Retrains максималдуу ашканда - окуя себеп менен 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 схемасы), ката коддорун документтештирүү.
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, чоң payloads.
Behavioral: out-of-order, дубликат, кечигүү 1-10 мүнөт, тыныгуу 24 саат.
Жүктөө: бурст 10 ×; backpressure жана DLQ туруктуулугун текшерүү.
Келишимдер: JSON схемасы, милдеттүү аталыштар, туруктуу окуялар түрлөрү.
15) Киргизүү чек-тизмеси
- 2xx = ACK, жана enqueue кийин тез кайтып
- Экспоненциалдык backoff + jitter, урматтоо 'Retry-After'
- "X-Webhook-Id" (TTL ≥ Retray) боюнча кабыл алуучунун жана Дедуптун аныктыгы
- HMAC кол, сырларды айлантуу, optional mTLS
- DLQ + Replay API, мониторинг жана Алерт
- Чектөөлөр: убакыт, RPS, дене өлчөмү
- Тартиби: partition by key же 'sequence' + "parking lot"
- Документтер: схемалар, мисалдар, ката коддору, нускалары
- Башаламандык-тесттер: кечигүү, эки эсе көп, тармак иштебей, узак replay
16) Mini-FAQ
Мен ар дайым 200 жооп бериши керекпи?
Ар кандай 2xx ийгилик катары эсептелет. 202/204 - кадимки практика үчүн "кабыл алынган кезек".
Кайталоону токтотууга болобу?
Ооба, 410 жооп жана/же консол/жөнөтүүчүнүн API аркылуу (жазылууну өчүрүү).
Чоң payloads жөнүндө эмне айтууга болот?
"Билдирүү + secure URL" жөнөтүү, жүктөп алуу өтүнүчүнө кол коюу жана TTL орнотуу.
тартипти кантип камсыз кылуу керек?
Partition by key + `sequence`; айырмачылыктар болгондо - "parking lot" жана кайталоо.
Жыйынтык
Ишенимдүү Webhuke - бул так ACK семантикасы (2xx), backoff + jitter менен акылга сыярлык кайталоолор, катуу демпотенттик жана дедупликация, компетенттүү коопсуздук (HMAC/mTLS), кезек + DLQ + реплика, жана тунук байкоо. Келишимди бекитиңиз, лимиттерди жана метриктерди киргизиңиз, дайыма башаламандык сценарийлерин кууп чыгыңыз - ошондо сиздин интеграцияларыңыз биринчи катачылыктарда "кулап" калат.