GH GambleHub

Намунаи Outbox

Outbox як намунаи меъморӣ мебошад, ки дар он хидмати домейн тағироти тиҷорат ва ҳодисаи мувофиқро дар як амалиёти маҳаллӣ ба анбори амонатии худ менависад. Интишори ҳодиса ба автобус/навбати беруна асинхронӣ тавассути раванди алоҳидаи бехатар (ношир) иҷро карда мешавад, ки ҷадвали 'outbox' -ро мехонад ва сабтҳоро паҳн мекунад. Ин равиш мусобиқаро "аввал ба пойгоҳи додаҳо, баъд ба автобус" бартараф мекунад ва ҳатто дар сурати нокомӣ расонидани боэътимодро таъмин мекунад.

1) Кай бояд муроҷиат кард

Мувофиқат:
  • Microservices ва монолитҳои модулӣ бо рӯйдодҳои байни контекстҳо.
  • Он талаб карда мешавад, ки "давлат собит шавад, ↔ ҳодиса гум нашавад".
  • Мо ба idempotence ва интиқоли назоратшаванда ниёз дорем.
Мувофиқ нест:
  • Амалиётҳои сахти глобалӣ оид ба якчанд захираҳо муҳиманд (беҳтар аз TCC/sagas бо шартномаҳои возеҳ).
  • Манбаи боэътимоди ҳақиқат вуҷуд надорад (давлат дар ҷое, ки ин чорабинӣ тавлид намешавад, нигоҳ дошта намешавад).

2) Ҳадафҳо ва хосиятҳо

Навиштани атомӣ: сабти домейн + outbox - дар як амалиёт.
Ҳадди аққал як бор нашр: мо ба такрор иҷозат медиҳем, талафотро истисно мекунем.
Idempotence истеъмолкунанда: муҳофизат аз ҷониби муштарӣ гирифта мешавад.
Маҳз як маротиба самаранок аст: тавассути омезиши outbox + истеъмолкунандаи idempotent + dedup.
Телеметрияи тоза - Таносуби муомилот ва рӯйдодҳои корӣ.

3) Схемаи маълумот (мисол)

sql
-- Domain table (example: orders)
CREATE TABLE orders (
id       UUID PRIMARY KEY,
tenant_id    TEXT NOT NULL,
status     TEXT NOT NULL,
total_amount  NUMERIC(12,2) NOT NULL,
updated_at   TIMESTAMP NOT NULL DEFAULT now()
);

-- Outbox
CREATE TABLE outbox (
id       UUID PRIMARY KEY,        -- event_id aggregate_type TEXT NOT NULL,          -- 'order'
aggregate_id  UUID NOT NULL,          -- order_id tenant_id    TEXT NOT NULL,
type      TEXT NOT NULL,          -- 'OrderCreated'
payload JSONB NOT NULL, -- serialized headers event JSONB NOT NULL DEFAULT '{}':: jsonb,
occurred_at TIMESTAMP NOT NULL, -- time in domain transaction available_at TIMESTAMP NOT NULL, -- earliest publish time (backoff)
published_at TIMESTAMP, - is filled by the attempts INT NOT NULL DEFAULT 0,
error      TEXT
);

CREATE INDEX ON outbox (available_at) WHERE published_at IS NULL;
CREATE INDEX ON outbox (tenant_id, available_at) WHERE published_at IS NULL;

4) Қабати барнома

pseudo begin tx domainChange () # INSERT/UPDATE in domain table insert into outbox (event) # event with aggregate/tenant commit tx keys

Агар ӯҳдадорӣ бомуваффақият бошад, ҳодиса дар outbox кафолат дода мешавад. Агар ариза пас аз содир шудан кам шавад, ношир онро пайдо мекунад.

5) Ношир (хонанда → ношир)

Вазифаҳо:
  • Ба таври даврӣ рӯйдодҳои нашрнашударо ('published _ at IS NULL' ва 'at _ at <= now ()'), маҷмӯаҳо хонед.
  • Кӯшиш кунед, ки ба автобус/навбат нашр кунед; агар муваффақ бошад, 'нашр _ at' -ро қайд кунед.
  • Дар ҳолати хатогӣ - зиёд кардани 'кӯшишҳо', 'дастрас _ at' барои оянда (бозгашти экспоненсиалӣ), 'хато' нависед.
  • Маҳдудиятҳои иҷорагирон/калидҳоро эҳтиром кунед (адолат), маҳсулотро манъ накунед.
Псевдокод:
pseudo loop:
events = select from outbox where published_at is null and available_at <= now()
order by occurred_at limit BATCH_SIZE for update skip locked

for e in events:
try:
broker. publish(topicFor(e), serialize(e. payload), headers(e))
markPublished(e. id, now())
except Retryable:
backoff = computeBackoff(e. attempts)
reschedule(e. id, now()+backoff, attempts+1, last_error)
except NonRetryable:
moveToDLQ (e) or markError (e) # by sleep (POLL_INTERVAL) policy
💡 'Барои навсозӣ SKIP LOCKED' рақобати ноширонро аз байн мебарад.

6) Номутобиқатӣ ва такрорӣ

Дар тарафи истеъмолкунанда (мағозаи паёмдони/Idempotency):
sql
CREATE TABLE inbox (
consumer_name  TEXT,
event_id    UUID,
processed_at  TIMESTAMP NOT NULL,
PRIMARY KEY (consumer_name, event_id)
);

Алгоритм: ҳангоми қабули ҳодиса, аввал кӯшиш кунед 'INSERT' -ро дар 'паёмдони'; агар як муноқишаи калидӣ вуҷуд дошта бошад, ҳодиса аллакай идора карда шудааст → no-op. Оянда мантиқи тиҷорат аст.

Дар тарафи ношир: 'Idempotency-Key' дар сарлавҳаҳо (масалан, 'event _ id'), то ки автобус/брокер/прокси нусхабардориро филтр кунад.

7) Тартиб ва сабабҳо

Тартиби маҳаллӣ аз ҷониби 'agregate _ id' бо навъбандии 'occured _ at' ва интишори "аз рӯи калид" таъмин карда мешавад.
Барои автобусҳои сабти тақсимот - қисмбандӣ бо калиди 'agregate _ id '/' иҷорагир _ ид', то ҳодисаҳои як агрегат дар як қисм бошанд.
Агар фармоиш муҳим бошад, аз нажодҳои яктарафаи ноширони яктарафа канорагирӣ кунед.

8) CDC (Тағйир додани сабти маълумот)

Ба ҷои ношири фаъол, шумо метавонед CDC-ро истифода баред: муҳаррик сабти транзаксияи пойгоҳи додаҳоро мехонад ва хатҳои 'outbox' -ро ба автобус тарҷума мекунад. Тарафдор - сарбории ҳадди аққал дар пойгоҳи додаҳо, пайдарҳамии дақиқ, овоздиҳӣ нест. Камбудиҳо - мураккабии амалиёт ва алоқамандӣ бо хусусиятҳои DBMS. Ҳарду равиш дурустанд; аз рӯи салоҳият ва SLO интихоб кунед.

9) Хатогиҳо, DLQ ва Redrive

Бозсозӣ (шабака, маҳдудиятҳо) - 'attempts' -ро зиёд кунед, 'avable _ at' -ро ба таъхир андозед (пушти экспоненсиалӣ + jitter).
Бознишаста (нақшаи/шартномаи беэътибор) - ба DLQ/Dead-Letter Topic бо метамаълумоти бой интиқол дода шудааст.
Redrive бехатар: Маҷмӯаҳо, меъёри маҳдудият, тасдиқи нақша, афзалият дар трафики истеҳсолӣ.

10) Иҷорапулӣ ва маҳдудиятҳо

Барчаспҳои талабшаванда: 'иҷорагир _ ид', 'нақша', 'минтақа' - дар 'outbox. сарлавҳаҳо '.
Адолати иҷорагир: ношир "тирезаҳо" -и нашрияҳо ва ҳудуди кӯшиши иҷорагиронро паҳн мекунад.
Резидентура: анборро дар ҳамон минтақа бо маълумоти домейн нигоҳ доред; нашри байниминтақавӣ - танҳо маҷмӯаҳо/хулосаҳо.

11) Бехатарӣ ва риояи

Нашри PII дар сарборӣ/сарлавҳаҳо оид ба сиёсати иҷорагир/минтақа.
Имзо/рамзгузории сарборӣ, агар автобус хориҷӣ бошад.
Аудити ҳамаи гузаришҳои давлатӣ: эҷод, нашр, хато, азнавсозӣ.

12) Мушоҳидакорӣ

Нишондиҳандаҳо:
  • Ақибмонии нашр ('ҳоло - occurred_at' p50/p95/p99).
  • Сатҳи муваффақият, сатҳи хатогӣ, тақсимоти сабаб.
  • Андозаи берунӣ (шумораи нашрнашуда), такрорӣ/сек
  • Графикҳои ба ҳар як иҷорагир гузаранда ва ақибмонда.
Пайгирӣ:
  • Таносуби 'event _ id '/' agregate _ id '/' saga _ id'; spans "db-tx", "нашр", "retry".
  • Эзоҳҳо: 'кӯшиш', 'backoff _ ms', 'dlq = ҳақиқат'.
Гузоришҳо:
  • Сабтҳои кӯтоҳ барои муваффақият; тафсилоти пурраи як хатогӣ/азнавсозӣ.

13) Озмоиш ва бетартибӣ

Санҷиши атомӣ: ба таври сунъӣ "афтид" пас аз содир кардани амалиёти домейн пеш аз интишор - чорабинӣ бояд баъдтар бароварда шавад.
Санҷиши такрорӣ: мо ҳамон як ҳодисаро якчанд маротиба нашр мекунем - истеъмолкунанда маҳз як эффектро иҷро мекунад (паёмдони паём).
Санҷиши фармоиш: маҷмӯи ҳодисаҳо аз рӯи як агрегат - пайдарпаӣ/idempotence.
Бесарусомонӣ: нокомии брокер, зиёд шудани таъхири пойгоҳи додаҳо, ноширони тақсимшуда, соатҳои корӣ.

14) Қолибҳои конфигуратсия (мисол)

yaml outbox:
poll_interval_ms: 200 batch_size: 200 order_by: occurred_at backoff:
strategy: exponential_full_jitter initial_ms: 250 max_ms: 10_000 max_attempts: 20 fairness:
per_tenant_parallelism: 4 per_key_serial: true

publisher:
rate_limit_per_sec: 500 headers:
idempotency_key: event_id schema_version: v3 dlq:
enabled: true topic: myapp. events. dlq include_metadata:
- error
- attempts
- source_table
- tenant_id
- aggregate_id

15) Ҳамгироӣ бо сагҳо ва ақибнишинӣ

Outbox - "нақлиёти амниятӣ" барои қадамҳои саёҳат: транзаксияи маҳаллӣ эффект ва фармон/ҳодисаро менависад; нашр - боэътимод ва доз.
Сиёсатҳои такрорӣ ва ақибмонӣ бояд бо 'Retry-After' ва Breaker Circuit мувофиқ бошанд; аз "тӯфони ақибнишинӣ" канорагирӣ кунед.

16) Хатогиҳои маъмулӣ

Онҳо пас аз содир кардани домени давлатӣ ҳодиса менависанд - талафот дар тирамоҳ имконпазир аст.
Ягон индексатсия/бойгонӣ дар 'outbox' § афзоиши таъхири нашр нест.
Ношир бидуни 'SKIP LOCKED' ё бидуни sharding - рақобат ва муҳосира.
Набудани idempotency дар байни истеъмолкунандагон - нусхабардорӣ ва таъсири тараф.
Омезиши PII бидуни ниқоб дар DLQ/гузоришҳо.
Навбати ягонаи нашрияи ҷаҳонӣ бидуни адолат - иҷорагири "ғавғо" ҳамаро суст мекунад.
Набудани мониторинги ақибмонӣ → таназзули ниҳонӣ.

17) Интихоби стратегияи зуд

Сатҳи оғоз: овоздиҳӣ аз пойгоҳи додаҳо, 100-500 партия, бозгашти пурраи ҷиттер, паёмдони барои истеъмолкунандагон.
Сарбории баланд: CDC аз дафтари муомилот, ки аз ҷониби 'иҷорагир _ ид/агрегат _ ид', WFQ аз ҷониби иҷорагир.
Тартиби қатъӣ аз рӯи маҷмӯа: нашри силсилавӣ барои як калид (мутекс), тақсимоти мавзӯъ бо калид.
Мувофиқат/PII: рамзгузории сарборӣ, нашри DLQ, баромади минтақавӣ.

18) Рӯйхати санҷиши пеш аз фурӯш

  • Тағйироти домейн ва навиштани 'outbox' дар як транзаксия рух медиҳанд.
  • Ношир партияҳоро идора мекунад, 'SKIP LOCKED' -ро истифода мебарад, бозгашт бо ҷиттер ва маҳдудиятҳо.
  • Истеъмолкунандагон idempotent мебошанд (ҷадвали 'паёмдони '/deadup log).
  • DLQ ва Release Secure танзим карда шудаанд.
  • Нишондиҳандаҳои хатогӣ ва ҳушдор дар ҳадди p95/p99.
  • Тартиби калидӣ кафолат дода мешавад (маҷмӯаҳо/сериалҳо).
  • Архив/нигоҳдории 'outbox' ва сабтҳои нашршудаи тоза.
  • Сиёсати PII ва аудити давлатии гузариш.
  • Санҷишҳо дар байни содир ва нашр, нусхабардорӣ ва фармоиш.
  • Ҳуҷҷатгузории шартномаи рӯйдодҳо (схемаҳо/версияҳо/мутобиқат).

Хулоса

Намунаи баромад бастаи "нозук" -и "DB ↔ автобус" -ро ба лӯлаи боэътимод табдил медиҳад: ислоҳи ҳолати атомӣ, ки кафолат дода шудааст (бо вуҷуди "ҳадди аққал як бор"), муштариёни idempotent ва redrave назоратшаванда. Бо интизоми дурусти телеметрия, маҳдудиятҳо ва схема, он рафтори амалии якдафъаина медиҳад, ки мураккабии транзаксияҳои тақсимшударо коҳиш медиҳад ва устувории системаро ба садама ва бори баландтарин афзоиш медиҳад.

Contact

Тамос гиред

Барои саволҳо е дастгирӣ ба мо муроҷиат кунед.Мо ҳамеша омодаем!

Telegram
@Gamble_GC
Оғози интегратсия

Email — муҳим аст. Telegram е WhatsApp — ихтиерӣ.

Номи шумо ихтиерӣ
Email ихтиерӣ
Мавзӯъ ихтиерӣ
Паем ихтиерӣ
Telegram ихтиерӣ
@
Агар Telegram нависед — ҷавобро ҳамон ҷо низ мегиред.
WhatsApp ихтиерӣ
Формат: рамзи кишвар + рақам (масалан, +992XXXXXXXXX).

Бо фиристодани форма шумо ба коркарди маълумот розӣ ҳастед.