Вебхуктарды жеткізу кепілдіктері
Вебхактар - HTTP (S) бойынша «жүйеден жазылушыға» асинхронды хабарламалар. Желі сенімді емес: жауаптар жоғалады, пакеттер телнұсқалармен немесе тәртіптен тыс келеді. Сондықтан жеткізу кепілдіктері «TCP бойынша» емес, вебхуктар мен домендік идемпотенттілік хаттамасының деңгейінде құрылады.
Түйінді мақсат: at-least-once-ді кілт бойынша ретпен жеткізуді қамтамасыз ету (қажет болған жерде), жазылушыға демпотенттік өңдеуге арналған материалдарды және қалпына келтіру үшін reconcile құралын беру.
1) Кепілдіктер деңгейлері
Best-effort - ретрассыз, бір реттік әрекет. «Маңызды емес» оқиғалар үшін ғана қолайлы.
At-least-once (ұсынылады) - көшірме және out-of-order болуы мүмкін, бірақ оқиға жазылушы ақылға қонымды мерзімде қол жеткізген жағдайда жеткізіледі.
Effectively-exactly-once (әсер деңгейінде) - жазылушы/жіберуші жағындағы демпотенттілік және dedup-сақтау комбинациясымен қол жеткізіледі. HTTP көлігінде «exactly-once» мүмкін емес.
2) Вебхук келісімшарты: ең аз қажетті
Тақырыптар (мысал):
X-Webhook-Id: 5d1e6a1b-4f7d-4a3d-8b3a-6c2b2f0f3f21 # глобальный ID события
X-Delivery-Attempt: 3 # номер попытки
X-Event-Type: payment.authorized.v1 # тип/версия
X-Event-Time: 2025-10-31T12:34:56Z # ISO8601
X-Partition-Key: psp_tx_987654 # ключ порядка
X-Seq: 418 # монотонный номер по ключу
X-Signature-Alg: HMAC-SHA256
X-Signature: t=1730378096,v1=hex(hmac(secret, t body))
Content-Type: application/json
Дене (мысал):
json
{
"id": "5d1e6a1b-4f7d-4a3d-8b3a-6c2b2f0f3f21",
"type": "payment.authorized.v1",
"occurred_at": "2025-10-31T12:34:56Z",
"partition_key": "psp_tx_987654",
"sequence": 418,
"data": {
"payment_id": "psp_tx_987654",
"amount": "10.00",
"currency": "EUR",
"status": "AUTHORIZED"
},
"schema_version": 1
}
Алушыға қойылатын талап: қолтаңбаны буферлеу және валидациялаудан кейін тез '2xx' жауап беру, ал бизнес-өңдеуді асинхронды жүргізу.
3) Тәртіп және себептері
Кілт бойынша тәртібі: кепілдік тек бір 'partition _ key' ішінде «кетпейді» (мысалы, 'player _ id', 'wallet _ id', 'psp _ tx _ id').
Жаһандық тәртіпке кепілдік берілмейді.
Жөнелтушінің жағында - кілт бойынша сериалдануы бар кезек (бір тұтынушы/шардинг), алушының жағында - inbox с '(source, event_id)' және өтіп кеткен 'seq' күтуі.
Егер ауытқулар қиын болса, pull-API 'GET/events беріңіз? after = checkpoint «қуып жету және салыстыру» мәртебесі үшін.
4) Ұқсастық және дедупликация
Әрбір вебхук тұрақты 'X-Webhook-Id' болады.
Алушы 'inbox (event_id)' сақтайды: PK - 'source + event_id'; қайталаулар → no-op.
Жанама әсерлер (ДБ/әмиянға жазу) оқиғаның бірінші «көрінісінде» бір рет қана орындалады.
«эффектімен» пәрмендері үшін Idempotency-Key және нәтижелер кэшін пайдаланыңыз.
5) Ретраялар, backoff және терезелер
Ретрайлер саясаты (референс):- '5xx/timeout/connection error/409-Conflict (retryable )/429' дегенге өңдеу.
- '409/423/429' дегеннен басқа '4xx' дегенге (және тек келісілген семантикада) қайта қарауға болмайды.
- Экспоненциалды backoff + full jitter: 0. 5s, 1s, 2s, 4s, 8s, … 'max = 10-15 мин' дейін; TTL терезе ретрайлері: мысалы, 72 сағат.
- Алушының 'Retry-After' -ін құрметтеу.
- Оқиғаны жеткізілмеген деп тану және оны DLQ-ге ауыстыру ортақ мерзімі болуы керек.
yaml retry:
initial_ms: 500 multiplier: 2.0 jitter: full max_delay_ms: 900000 ttl: 72h retry_on: [TIMEOUT, 5xx, 429]
6) DLQ и redrive
DLQ - улы немесе TTL бойынша толық метаақпараты бар оқиғалардың «зираты» (пэйлоад, тақырыптар, қателер, әрекеттер, хэштер).
endpoint/құпияны опциондық түзетумен redrive (нүктелі қайта жеткізу) үшін веб-консоль/API.
Rate-limited redrive және batch-redrive басымдықпен.
7) Қауіпсіздік
mTLS (мүмкіндігінше) немесе TLS 1. 2+.
Дененің қолы (per tenant/endpoint құпиясы бар HMAC). Тексеру:1. 't' (timestamp) тақырыбынан шығарыңыз, жылжымалы терезені тексеріңіз (мысалы, ± 5 мин).
8) Квоталар, rate limits және әділдік
Fair-Queue per tenant/subscriber: бір жазылушы/тенант ортақ пулды толтырмауы үшін.
Шығыс трафигіне квоталар мен burst-лимиттер және per-endpoint.
'429' реакциясы: 'Retry-After' оқу, тротлинг ағыны; ұзақ шектеу кезінде - degrade (оқиғалардың сыни түрлерін ғана жіберу).
9) Жазылудың өмірлік циклі
Register/Verify: POST endpoint → challenge/response немесе out-of-band растамасы.
Lease (қалауы бойынша): қолтаңба 'valid _ to' дейін қолданылады; ұзарту - анық.
Secret rotation: `current_secret`, `next_secret` с `switch_at`.
Test ping: Негізгі топиктерді қосу алдында бағытты тексеру үшін жасанды оқиға.
Health-сынамалар: latency және TLS профилін тексерумен мерзімді HEAD/GET.
10) Схемалардың эволюциясы (оқиғалар нұсқасы)
Оқиға түрінің нұсқасы: 'payment. authorized. v1` → `…v2`.
Эволюция - additive (жаңа өрістер → MINOR API нұсқасы), breaking → жаңа түрі.
Схемалар тіркелімі (JSON-Schema/Euro/Protobuf) + жөнелту алдындағы автоматты валидация.
'X-Event-Type' тақырыбы және 'schema _ version' өрісі - екеуі де міндетті.
11) Бақылау және SLO
Өлшемдері (түрі/теңгерімі/жазылушысы бойынша):- `deliveries_total`, `2xx/4xx/5xx_rate`, `timeout_rate`, `signature_fail_rate`.
- 'attempts _ avg', 'p50/p95/p99 _ delivery _ latency _ ms' (жарияланымнан 2xx дейін).
- `dedup_rate`, `out_of_order_rate`, `dlq_rate`, `redrive_success_rate`.
- `queue_depth`, `oldest_in_queue_ms`, `throttle_events`.
- Жеткізу үлесі ≤ 60 с (p95) - 99. Сыни оқиғалар үшін 5%.
- DLQ ≤ 0. 24 сағатта 1%
- Signature failures ≤ 0. 05%.
Логи/трейсинг: `event_id`, `partition_key`, `seq`, `attempt`, `endpoint`, `tenant_id`, `schema_version`, `trace_id`.
12) Жөнелтушінің референттік алгоритмі
1. Оқиғаны транзакциялық outbox бағдарламасына жазу.
2. partition_key және seq; кезекке қою.
3. Воркер кілт бойынша алады, сұрауды қалыптастырады, қол қояды, таймауттармен жібереді (connect/read).
4. '2xx' кезінде - жеткізілген деп тану, латенттілік пен seq-чек пунктін белгілеу.
5. Кезінде '429/5xx/timeout' - саясатқа сәйкес ретрай.
6. TTL → DLQ және алерт бойынша.
13) Референттік өңдеуші (алушы)
1. Сұрауды қабылдау, TLS/proto бағдарламасын тексеру.
2. Қолтаңба мен уақыт терезесін валидациялау.
3. Жылдам ACK 2xx (жергілікті inbox/кезекке синхронды жазғаннан кейін).
4. Асинхрондық воркер 'inbox' оқиды, 'event _ id' (дедуп) тексереді, қажет болған жағдайда 'seq' ішкі 'partition _ key' бойынша реттейді.
5. Эффекттерді орындайды, reconcile үшін «offset/seq чекпоинт» деп жазады.
6. Қате болған жағдайда - жергілікті ретрациялар; «улы» тапсырмалар → жергілікті DLQ алгоритмі бар.
14) Reconcile (пулл-контур)
«Өтпейтін» инциденттер үшін:- `GET /events? partition_key=...&after_seq=...&limit=...' - өткізіп алғандардың бәрін беру.
- 'after = opaque _ token' орнына seq.
- Іспеттес redelivery: сол 'event _ id', сол қолтаңба жаңа 't' бойынша.
15) Пайдалы тақырыптар мен кодтар
2xx - қабылдады (тіпті кейінірек бизнес-өңдеу болса да).
410 Gone - endpoint жабық (жіберуші жеткізуді тоқтатады және жазылымды «мұрағатқа» деп белгілейді).
409/423 - ресурсты уақытша бұғаттау → ретрай түсінікті.
429 - тым жиі → троттл және backoff.
400/401/403/404 - конфигурациялық қате; ретрацияны тоқтату, тикетті ашу.
16) Мульти-тенант және өңірлер
Жеке кезектер мен per tenant/endpoint лимиттері.
Data residency: деректерді аймақтан жіберу; өтпелі тақырыптар «X-Tenant», «X-Region».
Ақауларды оқшаулау: бір жазылушының құлауы қалғандарына әсер етпейді (separate pools).
17) Тестілеу
Contract tests: бекітілген телефон/қолтаңба мысалдары, валидацияны тексеру.
Chaos: drop/дубликаттар, shuffle тәртібі, желі кідірістері, 'RST', 'TLS' - қателер.
Load: burst-дауыл, өлшеу p95/p99.
Security: анти-реплика, ескірген timestamp, қате құпиялар, ротация.
DR/Replay: оқшауланған стендте DLQ-дан жаппай redrive.
18) Плейбуктар (runbooks)
1. 'signature _ fail _ rate' өсуі
Сағат дрейфін, өткен 'tolerance', құпиялардың ротациясын тексеру; «dual secret» уақытша қосылсын.
2. Кезек қартаюда ('oldest _ in _ queue _ ms' ↑)
Воркерлерді ұлғайту, сыни топиктердің басымдығын қосу, «шулы» типтердің жиілігін уақытша төмендету.
3. '429' дауылы
Троттлинг пен әрекеттер арасындағы үзілістерді қосу; оқиғалардың аз сыни түрлерін жылжыту.
4. Жалпы '5xx'
Нақты endpoint үшін circuit-breaker ашу, defer & batch режиміне ауыстыру; жазылушыға белгі беру.
5. DLQ толтыру
Сын емес жарияланымды тоқтату, RPS төмен batch-redrive қосу, жазылым иелеріне алерталарды көтеру.
19) Типтік қателер
Жауап беру үшін синхронды ауыр өңдеу 2xx → ретра және дубликаттар.
Дене/уақыт терезесінің қолтаңбасы жоқ → алмастыру/репликаға осалдығы.
'event _ id' және 'inbox' → жоқ.
«Жаһандық тәртіп» әрекеті → кезектерді мәңгілік бұғаттау.
Jitter/лимиттерсіз ретрайлер → оқиғаның күшеюі (thundering herd).
Барлық жазылушыларға арналған бірыңғай ортақ пул → «шулы» барлығын қояды.
20) Азық-түлік алдындағы чек-парағы
- Келісім-шарт: 'event _ id', 'partition _ key', 'seq', 'event _ type. vN ', қолы HMAC және timestamp.
- Жіберуші: outbox, кілт бойынша серияландыру, backoff + jitter, TTL, DLQ және redrive.
- Алушы: inbox + 2xx жылдам жазу; демпотенттік өңдеу; жергілікті DLQ.
- Қауіпсіздік: TLS, қолтаңбалар, анти-реплика, dual-secret, ротация.
- Квоталар/лимиттер: fair-queue per tenant/endpoint, құрмет 'Retry-After'.
- Reconcile API және чек пункттері; жазылушыларға арналған құжаттама.
- Бақылау қабілеті: p95/ағындар/қателер/DLQ, 'event _ id' бойынша трасса.
- Оқиғаларды нұсқалау және схемаларды эволюциялау саясаты.
- Оқиғалар ойнатқыштары және жаһандық үзіліс/еріту «түймесі».
Қорытынды
Сенімді вебхактар - жай ғана «JSON бар POST» емес, HTTP үстіндегі протокол. Нақты келісімшарт (ID, тәртіп кілті, қолтаңба), іспеттілік, jitter ретрасы, әділ кезек және жақсы реттелген плейбуктер «ең жақсы жағдайды» болжамды және өлшенетін жеткізу тетігіне айналдырады. At-least-once + кілт + reconcile бойынша тәртіпті жасаңыз және жүйе желіден, жүктеме шыңынан және адам қателіктерінен аман қалады.