GH GambleHub

Қайталау стратегиялары мен

1) Бұл не үшін қажет

Желілердегі істен шығулар - норма: таймауттар, transient-қателер, желілік флаппингтер, артық жүктеме. Ретраялар сенімділікті тек қана:

1. қайталау қауіпсіз (іспеттес),

2. қайталаулар арасында ұстамдар сақталады,

3. тәуелділіктің лимиттері/квоталары және «денсаулығы» құрметтеледі.

Мақсаты - жалған дубльдерсіз және жарыссыз бизнес-операциялар деңгейіндегі effectively-once мінез-құлық.

2) Жеткізу семантикасының таксономиясы

At-most-once: қайталаусыз, жоғалту тәуекелі (логизация, fire-and-forget).
At-least-once: дубликаттар болуы мүмкін → тұтынушының демпотенттігі қажет (көптеген кезектер, вебхактар).
Effectively-once: дубликаттар мүмкін, бірақ дұрыс дедуплицияланады (кілттер, транзакциялар, outbox).

3) Қашан ретрациялау, ал қашан емес

Ретраиттің мағынасы бар: '408', '429' ('Retry-After' сақтай отырып), '425' (Too Early), '499' (периметрде client closed), '5xx', '504', желілік таймауттар/үзіктер, шлюздегі '502', «connection reset».
'400/ 401/403/404/422' сұрауын өзгертпей ретраим болмайды.
Даулы жағдайлар: '409 Conflict' (әдетте ретраим емес; алдымен операция мәртебесін оқимыз/ниетін қайта растаймыз).

4) Таймауттар, backoff және джиттер

4. 1 Ереже

Алдымен таймаут, содан кейін ретрациялар: әрбір сұрауда «deadline» болуы керек.
Exponential backoff: 'delay _ n = base 2 ^ n', шектейміз 'max _ delay'.
Jitter міндетті: «доғал синхронды толқындарды» ажырату үшін кездейсоқ қосыңыз.

4. 2 Джиттер үлгілері

Full jitter: 'sleep = rand (0, base2 ^ n)' - ең жақсы жалпы таңдау.
Decorrelated jitter: 'sleep = min (max_delay, rand (base, sleep_prev3))' - ұзақ диалогтар үшін.
Equal jitter: 'sleep = base2 ^ n/2 + rand (0, base2 ^ n/2)' - жұмсақ вариация.

4. 3 Retry-budget

Ретрациялардың үлесін шектеңіз:
  • `retry_budget_per_min = max(α success_rps, floor β)`; әдетте 'α = 0. 1–0. 2`.
  • Бюджет таусылған кезде fail-fast/circuit breaker «open» -ке көшеміз.

5) rate limiting және Circuit Breaker өзара әрекеттесу

'Retry-After', 'RateLimit-Reset' -ті құрметтеңіз және оны бэк-оффта санаңыз.
Жоғары '5хх '/таймауттар кезінде - ретраялардың жиілігін және жалпы параллелизмді төмендетіңіз.

Circuit breaker:
  • Half-open: шектеулі сынамаға рұқсат береді.
  • Open: дереу ауытқиды (ресурсты үнемдейді).
  • Closed: кәдімгі жұмыс.
  • Write-операцияларда агрессивті ретраяларды айналдырудан гөрі 409/503 қайтарған дұрыс.

6) Write-операциялардың ұқсастығы

6. 1 Ортақ идея

Бірдей ниет → бір нәтиже. Негіз - сәйкестік кілті және орындау жазбаларының қоймасы.

6. 2 HTTP келісімшарты

Клиент келесі тақырыпты жібереді:

Idempotency-Key: 7a6b7f9e-2a46-4d0b-9c3a-2b30e1c3c9e3
Idempotency-Key-Expiry: 24h # optional
Сервер:
  • бірінші сәтті орындау кезінде сақтайды (кілт → нәтиже, мәртебе, дененің хеші);
  • қайталағанда бұрынғы жауап қайтарады және 'Idempotency-Replay: true' тақырыбы;
  • дене қақтығысы кезінде (сол кілт, бірақ басқа payload) - '409 Conflict'.

6. 3 Сақтау орны және TTL

Кесте/кілт-мән: 'idempotency _ key', 'request _ hash', 'result', 'status', 'expiry _ at'.
TTL = ықтимал қайталау және кеш жеткізу терезесі (әдетте төлемдер үшін 24-72 сағат).
'idempotency _ key' бойынша индекстер; жоғары жүктеме үшін - хеш бойынша шардалау.

6. 4 Схема үлгісі (SQL)

sql
CREATE TABLE idempo_store (
key UUID PRIMARY KEY,
req_hash BYTEA NOT NULL,
status INT NOT NULL,
response JSONB NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
expiry_at TIMESTAMPTZ NOT NULL
);

6. 5 Өңдеушінің жалған құжаты

pseudo handle_write(req):
k = req. headers["Idempotency-Key"]
h = hash(req. body)
rec = idempo_store. get(k)

if rec and rec. req_hash == h:
return rec. status, rec. response, {"Idempotency-Replay": "true"}

if rec and rec. req_hash!= h:
return 409, problem("IDEMPOTENT_CONFLICT")

begin tx result = apply_business_mutation (req) # change status upsert once (idempo_store, key = k, req_hash=h, status = 201, response = result, expiry = now () + 2d)
commit

return 201, result

7) «effectively-once» паттерндері

Transactional Outbox: бизнес-оқиғаны жазу және фон релейері арқылы сол БД-транзакциядан хабар жіберу; тұтынушы іспеттес.
Тұтынушыда Inbox/Processed-table: дубльді елемеу үшін 'event _ id' сақталады.
Kafka-да exactly-once бизнесте ≠ exactly-once: тіпті EOS продюсер/консумер кезінде де қолданбалы логика бәрібір идемотенттік болуы тиіс.
Компенсациялық транзакциялар (Saga): егер қадамдар кері қайтарылса және жанама әсерлер туындаса, жүйені инварианттарға қайтарамыз.

8) Жеке жағдайлар: төлемдер және қаржылық операциялар

Strong idempotency: кілт әрекеттің логикасына байланған (мысалы, 'external _ payment _ id').
PSP дедупликациясы: 'merchant _ reference' → бағдарламасын сақтаңыз.
«Клиенттен» ретрайлері: 'Idempotency-Key' кезінде ғана рұқсат етіледі, әйтпесе екі рет есептен шығару тәуекелі.
Бәсекелестік: орындау уақытында «аккаунтқа/құралға/шартқа» бұғаттау; қайталағанда 409/423 қайтарыңыз.
Бақылау мүмкіндігі: 'idempo _ replay _ total', 'idempo _ conflict _ total' өлшемдері.

9) Вебхактар және сыртқы шақырулар

HMAC қолтаңбалары және уақыт терезесі; алдымен тексеру, содан кейін өңдеу.
Жіберушінің ретрайлері: экспоненциалды backoff + джиттер, 'max _ attempts' және DLQ.
Тұтынушы - іспеттес: 'event _ id' → кесте/in-memory cache; «ұқыпты» тәртіпке кепілдік берілмеген.
Кодтар: 2xx = табысты, 4xx = қайталанбасын, 5хх/таймаут = қайталанбасын.

10) Кезектер және фондық міндеттер

Әдепкі бойынша At-least-once → қайталануы мүмкін емес.
'task _ id '/' event _ id' және орындалу күйін сақтаңыз; дубли кезінде - «replay» қысқа жолы.
DLQ және poison-messages: әрекеттер есептегіші, карантин, қолмен талдау.
Бәсекелестік лимиттер (семафорлар) және демпотенттік воркерлер.

11) Нұсқалау және «табиғи» кілттер

Заттай кілттер (шот нөмірі + күні + құжат нөмірі) қайталануларға төзімділікті арттырады.
Сұлбаны/нұсқаны ауыстырған кезде 'Idempotency-Key' немесе сұраудың хэшіне нұсқа кілтін қосыңыз.

12) HTTP тақырыптары және клиентке кеңестер

'Idempotency-Key', 'Idempotency-Replay', 'Retry-After', 'Prefer: wait = <sec>' (ұзақ операцияларда), 'If-Match '/' ETag' (оптимистік бұғаттау).
409 'Retry-After' валидті кілтпен 425/429/503 қайшылықта.
«Ұзын» операциялар үшін - асинхронды мәртебені қабылдау (мәртебе ресурсына '202 Accepted' + 'Location').

13) Тестілеу және хаос-сценарийлер

Negative-тесттер: екі рет жіберу, басқа денемен қайталау, сағат рассинхроны.
't2' тәртібінің бұзылуы 't1' -ден ерте келеді.
Таймауттарды инъекциялау/' RST '/' EOF ', жартылай сұраулар (slow-POST).
idempotency → құлдыраған сақтау орны fail-closed мінез-құлық (екі рет есептен шығарудан жақсы).

14) Метриктер мен алерталар

`retries_total{reason}`, `retry_budget_used{route}`, `backoff_seconds_bucket`.
`idempo_replay_total`, `idempo_conflict_total`, `duplicate_detected_total`.
Бағыттар бойынша 409/425/429/5xx үлесі; p95/p99 «табысқа дейінгі уақыт» ретрайлерімен.
Алерттар: ретрайлардың burn-rate бюджеті, дау-дамайлардың өсуі, DLQ өсуі.

15) Антипаттерндер

Қателерді ретке келтіру.
Джиттердің жоқтығы → ретрайлардың синхронды толқындары.
TTL және тазалаусыз ұзақ өмір сүретін кілттер.
Жанама әсер коммитінен кейін нәтижені сақтау (outbox бұзылуы).
'trace _ id '/' idempotency _ key' → логтары форензия мүмкін емес.
Write-операциялардағы агрессивті параллель ретрациялар.

16) Prod-дайындық чек-парағы

  • Бірыңғай саясат: не ретраим, не жоқ; клиенттің кодтары мен кеңестері.
  • Экспоненциалды backoff + full jitter; берілген 'retry _ budget'.
  • «Idempotency-Key» келісімшарты + TTL-мен нәтижелерді сақтау.
  • Оқиғалар үшін Outbox/Inbox; DLQ; бәсекелестік лимиттері.
  • circuit breaker, respect 'Retry-After' бағдарламасымен біріктіру.
  • Ретрациялар/дубликаттар/қайшылықтар бойынша метриктер/алерттар.
  • Хаос-тесттер жиынтығы және желілік іркілістерді эмуляциялау.
  • Клиенттерге арналған құжаттама: бэк-офф мысалдары мен мәртебелері.

17) TL; DR

Ретраялар демпотенттілігімен бірге ғана пайдалы. 'Idempotency-Key' және нәтижелер қоймасын енгізіңіз, джиттермен экспоненциалды backoff және retry-budget қолданыңыз, 'Retry-After' -ді құрметтеңіз, circuit breaker-мен интеграцияланыңыз. Оқиғалар үшін - outbox/inbox; төлемдер үшін - қатаң дедупликация және блокадалау. Ретрациялар мен қайшылықтарды өлшеңіз, дубликаттар мен таймауттарды тестілеңіз.

Contact

Бізбен байланысыңыз

Кез келген сұрақ немесе қолдау қажет болса, бізге жазыңыз.Біз әрдайым көмектесуге дайынбыз!

Telegram
@Gamble_GC
Интеграцияны бастау

Email — міндетті. Telegram немесе WhatsApp — қосымша.

Сіздің атыңыз міндетті емес
Email міндетті емес
Тақырып міндетті емес
Хабарлама міндетті емес
Telegram міндетті емес
@
Егер Telegram-ды көрсетсеңіз — Email-ге қоса, сол жерге де жауап береміз.
WhatsApp міндетті емес
Пішім: +ел коды және номер (мысалы, +7XXXXXXXXXX).

Батырманы басу арқылы деректерді өңдеуге келісім бересіз.