Medibox-pattern
Medibox-ը ճարտարապետական քարթրիջն է, որտեղ բյուջետային ծառայությունը գրում է բիզնես փոփոխությունը և համապատասխան իրադարձությունը իր պահեստում։ Իրադարձության հրապարակումը արտաքին անվադողերում/հերթում կատարվում է ասինխրոն առանձին անվտանգ գործընթացով (publisher), որը կարդում է «www.box» աղյուսակը և փոխանցում է գրառումները։ Այս մոտեցումը վերացնում է մրցավազքը «սկզբում BD, ապա անվադողերի մեջ» և ապահովում է հուսալի առաքում նույնիսկ ձախողումների ժամանակ։
1) Ե՞ րբ կիրառել
Հարմար է
Միկրովեռներ և մոդուլային մոնոլիտներ, որոնք տեղի են ունենում կոնտեքստների միջև։
Անհրաժեշտ է երաշխավորել, որ «վիճակը գրանցվել է ռուսական իրադարձությունը չի կարող կորցնել»։
Անհրաժեշտ է idempotenty և վերահսկվող կրկնվող առաքում։
Չի համապատասխանում
Խիստ գլոբալ գործարքները մի քանի ռեսուրսների վրա (ավելի լավ է TSS/sagi ակնհայտ պայմանագրերով)։
Ճշմարտության առանձնահատուկ աղբյուր չկա (state պահվում է այնտեղ, որտեղ իրադարձությունը կարգավորվում է)։
2) Նպատակներն ու հատկությունները
Atomic write: + www.box-ը մեկ գործարքում է։
At-leport-once հրատարակությունը 'թույլ տվեք խոհարար, բացառենք կորուստը։
Սպառողների idempotention 'պաշտպանություն կրկնություններից բաժանորդների կողմում։
Արդյունավետ exactly-once: ձեռք է բերվում www.box + idempotent consumer + 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) Գործարքային ձևանմուշը (applationlayer)
pseudo begin tx domainChange () # INSERT/UPDATE in domain table insert into outbox (event) # event with aggregate/tenant commit tx keys
Եթե կոմունիտը հաջողակ է, ռուսական բլոկում իրադարձությունը երաշխավորված գոյություն ունի։ Եթե ծրագիրը ընկնի կոմունիտից հետո, պաբլիշերը կհասնի։
5) Pablisher (reader publisher)
Առաջադրանքներ
Պարբերաբար կարդալ չհրապարակված իրադարձությունները ("published _ at IS NSA" և "available _ at <= now (), մարտեր։
Փորձել հրապարակել անվադողերի/հերթերի մեջ։ հաջողության դեպքում 'նշել «published _ at»։
Սխալմամբ 'ավելացնել «attemprone», տեղադրել «available _ at» ապագայի վրա (exponential backoff), գրել «error»։
Հարգել tenants/fairness (fairness), ոչ թե արգելափակել։
Prindocod
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
6) Idempotenty և deduplication
Սպառողի կողմում (Inbox/Idempotency store)
sql
CREATE TABLE inbox (
consumer_name TEXT,
event_id UUID,
processed_at TIMESTAMP NOT NULL,
PRIMARY KEY (consumer_name, event_id)
);
Ալգորիթմը 'իրադարձություն ստանալիս, նախ «INSSA» փորձարկումը' «inbox»; Եթե ստեղնաշարի հակամարտությունը արդեն մշակվել է «2019-op» տերմինալի միջոցով։ Հաջորդը բիզնես տրամաբանությունն է։
Պաբլիշերի կողմում '«Idempotency-Key» -ը headers-ում (օրինակ ՝ «event _ id»), որպեսզի անվադողը/brocer/105-ը կարողանան ֆիլտրել կրկնօրինակները։
7) Կարգը և պատճառները
Տեղական կարգը «aggregate _ id» -ը ապահովվում է «occcurred _ at» և «բանալին» հրատարակությամբ։
Log-shin-ի համար, նվագակցելով «aggregate _ id _ id» բանալին, որպեսզի մեկ միավորի իրադարձությունները մեկ խմբաքանակի մեջ լինեն։
Եթե կարգուկանոնը կրիտիկական է, խուսափիր պաբլիտերի միջմայրցամաքային մրցումներից։
8) CDC (Change Data Capture)
Ակտիվ պաբլիշերի փոխարեն դուք կարող եք օգտագործել CDC-ը 'շարժիչը կարդում է BD գործարքների ամսագիրը և փոխանցում է «www.box» տողերը անվադողին։ Պլյուսները նվազագույն են BD-ի վրա, ճշգրիտ հաջորդականությունը, պոլինգի բացակայությունը։ Minus-ը վիրահատության բարդությունն է և SUBD-ի առանձնահատկությունները։ Վադինի երկու մոտեցումները. ընտրեք իրավասությունները և SLO-ն։
9) Սխալներ, DLQ և redraiv
Retryable (ցանց, լիմիտներ) - ավելացնում ենք «attemprone», մենք դնում ենք «available _ at» (exponential backoff + jitter)։
Non-retryable (ոչ որակյալ սխեմա/պայմանագիր) - մենք տեղափոխում ենք DLQ/Dead-Letter Topic հարուստ մետատվյալներով։
Ապահով ռեդրեյվը 'մարտեր, rate-limit, սխեմայի վալիդացիա, առաջնահերթություն ցածր, քան prod-2019-ը։
10) Մուլտֆիլմը և լիմիտները
Պարտադիր թեստեր ՝ «tenrone _ id», «plan», «region» - «box»։ headers`.
Per-tenault fairness: pabliker բաժանում է հրատարակությունների «պատուհանները» և վարձակալների փորձերի սահմանները։
Residency: Պահեք www.box նույն տարածքում, որտեղ հիբրիդային տվյալները; միջտարածաշրջանային հրատարակությունը միայն ագրեգատներ/կամարներ է։
11) Անվտանգություն և համապատասխանություն
PII-խմբագրությունը payload/headers քաղաքականության վրա։
Փոխանակման բեռի ստորագրումը/կոդավորումը, եթե անվադողը «օտար» է։
Պետության բոլոր անցումների աուդիտը 'ստեղծված, հրատարակված, սխալ, ռեդրեյվ։
12) Դիտողականությունը
Մետրիկները
Հրապարակման լագը ("now - occurred _ at 'p50/p95/p99)։
Հաջողության մասնաբաժինը, սխալների մասը, պատճառների բաշխումը։
Www.box (col-ը չհրապարակված), փորձեր/վրկ։
Troughput-tenant գրաֆիկները և lag-ը։
Թրեյսինգը
«Event _ id »/« aggregate _ id »/« saga _ id»; «db-tx», «publish», «retry»։
Սենսացիաներ ՝ «attempt», «backoff _ 104», «dlq = 108»։
Լոգի
Հաջողության հակիրճ գրառումները. ամբողջական մանրամասներ սխալի/ռեդրեյվների վերաբերյալ։
13) Փորձարկում և քաոս
Atomicity թեստը 'արհեստականորեն «ընկնում» մետրոպոլիտենի գործարքից հետո մինչև հրապարակումը, իրադարձությունը պետք է ավելի ուշ դուրս գա։
Duplicate թեստ 'մենք հրապարակում ենք նույն event-ը մի քանի անգամ' կոնսուումերը կատարում է հենց մեկ ազդեցություն (inbox)։
Օրդեր թեստ 'մի միավորի իրադարձությունների պաչկ' հաջորդականության/idempotenty ստուգում։
Chaos 'բրոքերի հրաժարվելը, BD-ի լատենտության աճը, split-brain pablikers, clock-skew։
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) Ինտեգրումը սագերի և գետերի հետ
Medibox-ը «անվտանգության տեղափոխություն» սագայի քայլերի համար. Տեղական գործարքը գրում է էֆեկտը և թիմը/իրադարձությունը։ հրապարակումը վստահելի և հետադարձելի է։
Խոհարարների և backoff քաղաքականությունները պետք է համաձայնվեն «Retry-After» և Circuit Breaker-ի հետ։ խուսափեք «փոթորիկից»։
16) Տիպիկ սխալներ
Նրանք գրում են իրադարձությունը բնակարանային վիճակից հետո, հնարավոր է կորուստ ընկնելիս։
Չկա ինդեքսներ/արխիվներ «www.box» -ում հրատարակման ուշացման աճ։
Պաբլիշերը առանց «SKIP SYKED» կամ առանց շարդիզացիայի մրցակցություն և արգելափակում է։
Սպառողների մոտ idempotenty բացակայությունը դուբլի և կողմնակի ազդեցություններ են։
PII-ի խառնուրդը առանց դիմադրելու DLQ/logs-ում։
Հրատարակման միասնական համաշխարհային հերթը առանց fairness-ի '«աղմկոտ» տենանտը խոչընդոտում է բոլորին։
Լագայի մոնիտորինգի բացակայությունը թաքնված դեգրադացիաներ է։
17) Ռազմավարության արագ ընտրություն
Մեկնարկային մակարդակը 'BD կիսագունդը, 100-500, fox-jitter backoff, inbox վահանակների մոտ։
Բարձր ստանդարտ 'CDC գործարքների ամսագրից, շարդինգը' «tenrone _ id/aggregate _ id», WFQ վարձակալողների վրա։
Ագրեգատային խիստ կարգը 'per key (mutex) սերիական հրատարակումը, տեղանունի խմբաքանակը բանալին։
Complaens/PII 'payload կոդավորումը, DLQ-ի խմբագրությունը, տարածաշրջանային բոքբոբը։
18) Չեկ թուղթ մինչև վաճառելը
- Էքսպորտային փոփոխությունները և ձայնագրությունը «www.box» -ում տեղի են ունենում մեկ գործարքում։
- Պաբլիշերը զարգացնում է մարտերը, օգտագործում է «SKIP SYKED», backoff ջիթերի և սահմանների հետ։
- Consumers idempotentna (wwww.inbox '/dedup ամսագիր)։
- DLQ-ը և անվտանգ ռեդրեյվը։
- Լագայի/սխալների և ալտերտերի վրա p95/p99։
- Բանալիների կարգը երաշխավորված է (կուսակցություն/սերիա)։
- Արխիվ/retenshn 'www.box "և հրատարակված գրառումների մաքրումը։
- PII քաղաքականությունը և պետությունների անցումների աուդիտը։
- Համայնքի և հրապարակման միջև ընկնելու թեստերը, կրկնօրինակները և կարգը։
- Մոսկովյան իրադարձություններ (սխեմաներ/տարբերակներ/համատեղելիություն)։
Եզրակացություն
Medibox-pattern-ը վերածում է «փխրուն» BD prodshin-ի հուսալի փոխակրիչի 'պետության ատոմային ամրագրումը, որը երաշխավորված է (չնայած «առնվազն մեկ անգամ») հրապարակումը, idempotent բաժանորդները և վերահսկվող ռեդրեյվը։ Ճիշտ հեռաչափության, սահմանաչափերի և սխեմաների կարգապահության դեպքում այն տալիս է գործնական exactly-once վարքագիծ, նվազեցնելով բաշխված գործարքների բարդությունը և բարձրացնելով համակարգի կայունությունը ձախողումների և պիկի բեռների նկատմամբ։