Gwarancje dostawy Webhook
Webhaki są asynchronicznymi powiadomieniami od systemu do abonenta przez HTTP (S). Sieć jest nierzetelna: odpowiedzi są tracone, pakiety pojawiają się w duplikatach lub nie w porządku. Dlatego gwarancje dostawy nie są zbudowane „nad TCP”, ale na poziomie protokołu webhook i domeny idempotence.
Kluczowym celem jest dostarczenie co najmniej jednorazowej dostawy za pomocą klucza (w razie potrzeby), dostarczenie materiałów abonenckich do idempotentnego przetwarzania i uzgodnienie narzędzia do przywracania.
1) Poziomy gwarancji
Najlepszy wysiłek - jednorazowa próba, bez retras. Dopuszczalne tylko dla „nieistotnych” wydarzeń.
Co najmniej raz (zalecane) - możliwe są duplikaty i poza zamówieniem, ale wydarzenie zostanie dostarczone pod warunkiem, że abonent będzie dostępny w rozsądnym terminie.
Efektywnie dokładnie raz (na poziomie efektu) - osiągnięty przez połączenie idempotencji i pamięci dedup po stronie abonenta/nadawcy. Transport HTTP „dokładnie raz” nie jest możliwy.
2) Umowa Webhook: minimum wymagane
Nagłówki (przykład):
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
Ciało (przykład):
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
}
Wymaganie dla odbiorcy: szybka odpowiedź '2xx' po buforowaniu i walidacji podpisu oraz asynchroniczne przetwarzanie biznesowe.
3) Porządek i przyczynowość
Kolejność kluczy: gwarancja „nie pozostawi” tylko w jednym 'partition _ key' (np. 'player _ id',' wallet _ id', 'psp _ tx _ id').
Globalny porządek nie jest gwarantowany.
Po stronie nadawcy jest kolejka z serializacją przez klucz (jeden konsument/shading), po stronie odbiorcy jest skrzynka odbiorcza z '(źródło, event_id)' i opcjonalnie czeka na brakujące 'seq'.
Jeśli luki są krytyczne - dostarczyć pull-API 'GET/wydarzenia? po = punkt kontrolny 'dla „nadrobić zaległości i skonsultować się”.
4) Idempotencja i deduplikacja
Każdy hak przenosi stabilny 'X-Webhook-Id'.
Odbiorca przechowuje 'skrzynkę odbiorczą (event_id)': PK - 'source + event_id'; powtarza → no-op.
Efekty uboczne (zapisanie do bazy danych/portfela) są wykonywane tylko raz, gdy zdarzenie jest po raz pierwszy „widziane”.
W przypadku poleceń z efektem użyj Idempotency-Key i pamięci podręcznej wyników na czas trwania okna przekaźnika.
5) Retrai, backoff i okna
Polityka retrasy (odniesienie):- Przekrój na '5xx/timeout/connection error/409-Conflict (retryyyable )/429'.
- Nie wycofywać się na '4xx' z wyjątkiem '409/423/429' (i tylko z spójną semantyką).
- Wykładniczy backoff + pełny jitter: 0. 5s, 1s, 2s, 4s, 8s,... do 'max = 10-15 min'; Okna retrasy TTL: na przykład 72 godziny.
- Szacunek dla 'Retry-After' od odbiorcy.
- Mają wspólny termin: „rozpoznać wydarzenie jako nie dostarczone” i przenieść go do 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 - „cmentarz” jadowitych lub TTL-wygasłych zdarzeń z pełnymi meta informacji (ładunek, nagłówki, błędy, próby, hashes).
Konsola internetowa/API do przekierowywania (przekierowanie punktu) z opcjonalnym punktem końcowym/tajną edycją.
Ograniczona stawka redrive i batch-redrive priorytetowo.
7) Bezpieczeństwo
mTLS (jeśli to możliwe) lub TLS 1. 2+.
Podpis nadwozia (HMAC z tajemnicą na najemcę/punkt końcowy). Weryfikacja:1. Wyciąg nie '(znacznik czasu) z nagłówka, sprawdź okno przesuwne (na przykład, ± 5 minut).
8) Kwoty, limity stóp procentowych i kapitał własny
Fair-Queue na najemcę/abonenta: tak, że jeden abonent/najemca nie zdobywa ogólnej puli.
Kwoty i limity pęknięcia dla ruchu wychodzącego i punktu końcowego.
Reakcja na '429': honor 'Retry-After', strumień trolla; dla długoterminowego ograniczenia - degradacja (wysyłanie tylko typów zdarzeń krytycznych).
9) Cykl życia subskrypcji
Zarejestruj/Sprawdź: punkt końcowy POST → wyzwanie/odpowiedź lub potwierdzenie poza pasmem.
Dzierżawa (opcjonalna): podpis jest ważny do „valid _ to”; przedłużenie - wyraźne.
Sekret rotacji: 'current _ secret', 'next _ secret' 'switch _ at'.
Test ping: sztuczne zdarzenie, aby przetestować trasę przed włączeniem głównych tematów.
Próbki zdrowotne: okresowe HEAD/GET z opóźnieniem i sprawdzeniem profilu TLS.
10) Ewolucja programów (wersje wydarzeń)
Typ zdarzenia wersioning: 'płatność. autoryzowany. v1 "→"... v2 ".
Evolution - dodatek (nowe pola → wersje MINOR API), łamanie → nowy typ.
Rejestr schematu (JSON-Schema/Avro/Protobuf) + automatyczna walidacja przed złożeniem wniosku.
Nagłówek 'X-Event-Type' i 'schema _ version' field w ciele są wymagane.
11) Obserwowalność i SLO
Mierniki (według typu/najemcy/abonenta):- 'deliveries _ total', '2xx/4xx/5xx _ rate', 'timeout _ rate', 'signature _ fail _ rate'.
- „attempts _ avg”, „p50/p95/p99 _ delivery _ latency _ ms” (publikacja do 2xx).
- 'dedup _ rate', 'out _ of _ order _ rate', 'dlq _ rate', 'redrive _ success _ rate'.
- 'queue _ depth', 'most _ in _ queue _ ms', 'throttle _ events'.
- Udział dostaw ≤ 60 s (p95) - 99. 5% dla zdarzeń krytycznych.
- DLQ ≤ 0. 1% w ciągu 24 godzin
- Awarie podpisu ≤ 0. 05%.
Лова/тревсин, "event _ id'," partition _ key "," seq "," attempt "," endpoint "," tenin _ id', "schema _ version", "trace _ id'.
12) Algorytm odniesienia nadawcy
1. Pisz zdarzenie do skrzynki operacyjnej.
2. Zdefiniuj partition_key i następne; kolejki.
3. Pracownik przyjmuje przez klucz, tworzy żądanie, znaki, wysyła z terminami (podłączyć/przeczytać).
4. Z '2xx' - rozpoznać jako dostarczone, naprawić opóźnienia i seq-punkt kontrolny.
5. Z '429/5xx/timeout' - wycofać się zgodnie z polityką.
6. Przez TTL → DLQ i alert.
13) Procesor referencyjny (odbiornik)
1. Zaakceptuj żądanie, sprawdź TLS/proto.
2. Walidacja podpisu i okna czasowego.
3. Szybki ACK 2xx (po synchronicznym zapisaniu do lokalnej skrzynki odbiorczej/kolejki).
4. Asynchroniczny pracownik odczytuje 'skrzynkę odbiorczą', sprawdza 'event _ id' (dziadek), w razie potrzeby, zamówienia przez' seq 'wewnątrz' partition _ key '.
5. Wykonuje efekty, pisze „offset/seq checkpoint” dla pogodzenia.
6. W przypadku błędu - lokalne przekładki; „trujące” zadania → lokalny DLQ z wpisami.
14) Reconcile (pętla basenowa)
W przypadku „nieprzeniknionych” incydentów:- "GET/wydarzenia? partition_key=...&after_seq=...&limit=...' - dać wszystko, czego brakuje.
- Punkt kontrolny tokena: 'after = opaque _ token' zamiast seq.
- Idempotent redelivery: ten sam 'event _ id', ten sam podpis na nowym' t'.
15) Przydatne nagłówki i kody
2xx - akceptowane (nawet jeśli przetwarzanie biznesowe jest późniejsze).
410 Odszedł - punkt końcowy jest zamknięty (nadawca zatrzymuje dostawę i oznacza abonament jako „archiwizowany”).
409/423 - tymczasowe blokowanie zasobów → retray jest rozsądne.
429 - zbyt często → przepustnica i cofanie.
400/401/403/404 - błąd konfiguracji; Zatrzymaj retrai, otwórz bilet.
16) Wieloosobowy najemca i regiony
Poszczególne kolejki i limity na najemcę/punkt końcowy.
Miejsce zamieszkania danych: wysyłanie danych z regionu; nagłówki końcowe „X-Najemca”, „X-Region”.
Izolacja awarii: upadek jednego abonenta nie wpływa na resztę (oddzielne puli).
17) Badanie
Testy kontraktowe: stałe przykłady jednostek/podpisów, kontrola walidacji.
Chaos: duplikaty, zlecenie shuffle, opóźnienia sieciowe, 'RST', błędy 'TLS'.
Obciążenie: burza wybuchowa, mierzona p95/p99.
Bezpieczeństwo: anty-powtórka, przestarzały znacznik czasu, błędne sekrety, obrót.
DR/Replay: Przekrój masy z DLQ w izolowanym stoisku.
18) Playbooks (książki startowe)
1. Wzrost „signature _ fail _ rate”
Sprawdź dryf zegara, wygasła „tolerancja”, obrót tajemnic; tymczasowo włączyć „podwójny sekret”.
2. Kolejka jest starzejąca ('najstarszy _ in _ queue _ ms')
Zwiększenie liczby pracowników, umożliwienie priorytetyzacji tematów krytycznych, tymczasowe zmniejszenie częstotliwości występowania „hałaśliwych” typów.
3. Burza „429” na abonenta
Włączyć przepuszczanie i pauzy między próbami; przesunięcie mniej krytycznych typów zdarzeń.
4. Masa „5xx”
Otwarty wyłącznik dla określonego punktu końcowego, przełącznik na odroczenie & batch; sygnał do abonenta.
5. Populacja DLQ
Przestań publikować bez krytycznego znaczenia, włącz redrive partii z niskim RPS, podnieść alerty do właścicieli subskrypcji.
19) Typowe błędy
Synchroniczne ciężkie przetwarzanie do 2xx odpowiedzi → przekładki i duplikaty.
Brak sygnatury okna ciała/czasu → substytucja/luka powtórzenia.
Brak 'event _ id' i' inbox '→ nie może być idempotentny.
Próba „globalnego porządku” → wieczne zamki kolejki.
Odwrót bez jitter/limitów → nasilenie incydentu (grzmot stada).
Pojedynczy wspólny basen dla wszystkich abonentów → „hałaśliwy” stawia wszystkich.
20) Lista kontrolna przedsprzedaży
- Umowa: 'event _ id',' partition _ key ',' seq ',' event _ type '. Podpis i znacznik czasowy vN ', HMAC.
- Nadawca: outbox, serializacja za pomocą klucza, przekładki z backoff + jitter, TTL, DLQ i redrive.
- Odbiorca: szybko napisz do skrzynki odbiorczej + 2xx; leczenie idempotentne; lokalny DLQ.
- Bezpieczeństwo: TLS, podpisy, anty-replay, dual-secret, rotacja.
- Kwoty/limity: sprawiedliwa kolejka na najemcę/punkt końcowy, przestrzeganie „Retry-After”.
- Uzgodnić interfejsy API i punkty kontrolne; dokumentacja dla abonentów.
- Obserwowalność: p95/threads/errors/DLQ, śledzenie 'event _ id'.
- Weryfikacja wydarzeń i polityka ewolucji schematu.
- Odtwarzacze incydentów i globalny przycisk pauzy/rozmrażania.
Wniosek
Zaufane haki są protokołem na górze HTTP, nie tylko "POST z JSON. "Jasny kontrakt (ID, klucz zamówienia, podpis), idempotencja, przekaźnik z jitterem, sprawiedliwa kolejka i dobrze debugowane playbooks zmieniają najlepszy przypadek w przewidywalny i wymierny mechanizm dostawy. Zbuduj co najmniej raz + kolejność kluczy + pogodzić, a system spokojnie przetrwać sieć, szczyty obciążenia i błędy ludzkie.