Оқиға архитектурасы
Оқиға сәулеті (EDA)
1) Оқиға не және неге EDA
Оқиға - доменде болған өзгермейтін факт («PlayerVerified», «PaymentCaptured»). EDA осы фактілер мен оларға реакцияларды жариялау төңірегінде интеграция құрады:- сервистердің әлсіз байланысы,
- тұтынушыларды тәуелсіз,
- реплика/проекцияларды қайта құру,
- айқын аудит.
EDA синхронды API-ны жоймайды - ол оларды асинхрондық қабатқа кросс-сервистік тәуелділіктерді шығарып, толықтырады.
2) Оқиға түрлері
Домендік: маңызды бизнес-фактілер (OrderPlaced, BonusGranted).
Интеграциялық: сыртқы жүйелерге арналған «суреттер «/өзгерістер (UserUpdated, WalletBalanceChanged).
Техникалық: өмірлік цикл және телеметрия (Heartbeat, PipelineFailed).
Командалар (оқиға емес, бірақ қатар): «X жасау» (CapturePayment) нұсқаулары.
Ұсыным: домендік оқиғалар - бастапқы; интеграциялық нақты тұтынушылар үшін проекциялармен қалыптастырылады.
3) Оқиғалардың келісімшарттары мен схемалары
Схема: Avro/Protobuf/JSON Schema + Schema Registry; үйлесімділік стратегиясы: «BACKWARD» тұтынушылардың эволюциясы үшін, «FULL» сындарлы тақырыптарда.
CloudEvents (id, source, type, time, subject, datacontenttype) - біркелкі тақырыптар.
Міндетті метадеректер: 'event _ id' (ULID/UUID), 'occurred _ at', 'producer', 'schema _ version', 'correlation _ id '/' causation _ id', 'idempotency _ key'.
Нұсқалау: add-only өрісі, қайта атауға/семантикалық бұзуға тыйым салу; жаңа түрлері - жаңа тақырыптар/түрлері.
json
{
"type":"record","name":"PaymentCaptured","namespace":"events.v1",
"fields":[
{"name":"event_id","type":"string"},
{"name":"occurred_at","type":{"type":"long","logicalType":"timestamp-micros"}},
{"name":"payment_id","type":"string"},
{"name":"amount","type":{"type":"bytes","logicalType":"decimal","precision":18,"scale":2}},
{"name":"currency","type":"string"},
{"name":"player_id","type":"string"}
]
}
4) Жеткізу, тәртібі және келісу
At-least-once дефолт ретінде → өңдеушілердің іспеттілігі қажет.
Тәртіп: партия (Kafka) немесе кезек (RabbitMQ) ішінде кепілдендіріледі, бірақ ретра кезінде бұзылуы мүмкін; оқиғаның кілті реттің домендік түйіршігін көрсетуі керек (мысалы, 'player _ id').
Келісімділік: ақша/кредиттер үшін - тек журналдар/сағдар/өтемақылар арқылы; LWW болдырмаңыз.
Оқу моделі: проекциялар мен кэштер eventual болуы мүмкін - «жаңарту жүріп жатыр»... көрсетіңіз және қатаң жолдар үшін RNOT стратегияларын пайдаланыңыз.
5) Outbox/Inbox и CDC
Outbox: сервис фактіні өзінің ДБ-сына және outbox кестесіне бір транзакцияда жазады → воркер шинаға жариялайды.
Inbox: тұтынушы 'event _ id' дегенді дедуп үшін өңдеу нәтижесімен сақтайды.
CDC (Change Data Capture): бағдарламаны өзгертпей интеграцияларды құру үшін ДБ-дан (binlog/WAL) шинаға өзгерістер ағыны.
Idempotency: 'idempotency _ key '/' event _ id' бойынша өңдеу, бекітілгенге дейін сыртқы әлемді өзгертпеу.
6) CQRS и Event Sourcing
CQRS: write моделін және read-проекцияларын бөлісу; проекциялар оқиғалардан құралады және артта қалуы мүмкін.
Event Sourcing: агрегаттың күйі = оның оқиғаларын жинақтау. Артықшылықтары: толық аудит/реплика; кемшіліктері: көші-қонның/схеманың/снапшоттың күрделілігі.
Практика: ES - барлық жерде емес, тарих пен өтемақы маңызды жерде; CQRS - әрқашан дерлік EDA-да.
7) Сағалар: оркестрлеу және хореография
Оркестрлеу: үйлестіруші команда жібереді және жауап-оқиғаларды күтеді; күрделі процестер үшін қолайлы (KYC → Deposit → Bonus).
Хореография: сервистер бір-бірінің оқиғаларына әсер етеді; оңай, бірақ бақылап отыру қиынырақ.
Өтемақылар мен қадамдардың мерзімін әрқашан анықтаңыз.
8) Топологияларды жобалау (Kafka/RabbitMQ)
Kafka
'payments. captured. v1`, `players. verified. v1`.
Партиялану кілті: 'player _ id '/' wallet _ id' - тәртіп маңызды жерде.
`replication. factor=3`, `min. insync. replicas = 2 ', продьюсер' acks = all '.
Retention: уақыт бойынша (мысалы, 7-90 күн) және/немесе compaction (кілт бойынша соңғы күйі).
backoff бар retry және DLQ арналған топиктер.
RabbitMQ
Exchanges: `topic`/`direct`, routing key `payments. captured. v1`.
Кең фан-аут үшін - 'topic' + бірнеше кезек; RPC/командалар үшін - жеке кезектер.
HA үшін Quorum Queues; Ретрациялар үшін TTL + dead-letter exchange.
9) Бақылау және SLO EDA
SLI/SLO:- End-to-end latency (occurred_at → өңделген): p50/p95/p99.
- Lag/age: тұтынушылардың артта қалуы (Kafka consumer lag, Rabbit backlog age).
- Жариялау/өңдеу Throughput.
- DLQ-rate және қайталау үлесі.
- Бизнес-операциялардың табысы (мысалы, «депозит 5с ≤ расталды»).
- 'trace _ id '/' correlation _ id' (OTel) арқылы оқиғаларды корреляциялау.
- Метрикадан (exemplars) даналары → трасса.
- Burn-rate алерті бар «Producer → Broker → Consumer» дашбордтары.
10) Реплика, ретеншн және backfill
Проекцияларды/қателерді түзетуге арналған реплика: жаңа проекцияға/неймспейске айдаңыз, содан кейін оқуды ауыстырыңыз.
Ретеншн: заңды/бизнес талаптар (GDPR/PCI); сезімтал өрістер - шифрлау және/немесе токенизациялау.
Backfill: бір реттік тақырыптар/кезектер, нақты RPS лимиттері.
11) Қауіпсіздік және комплаенс
TLS in-transit, mTLS ішкі клиенттер үшін.
Авторизация: per-topic/per-exchange ACL; multitenancy namespace/vhost арқылы.
PII: оқиғадағы өрістерді азайту; envelope метадеректер бөлек, пайдалы жүктемелер қажет болған жағдайда шифрланады.
Оқиғаларға қол жеткізу аудиті, «барлық мүмкін» кілттерге тыйым салу.
Ретеншн саясаты және жою құқығы (GDPR): деректер сілтемелерін немесе tombstone оқиғаларын және жою жобаларын сақтаңыз.
12) EDA тестілеу
Contract tests: тұтынушылар өздерінің күткен схемаларын (consumer-driven) валидациялайды.
Replay-тесттер: жаңа өңдегіш/схема нұсқасы арқылы тарихи іріктемені айдап өту.
Chaos сценарийлері: брокердің кідіруі/жоғалуы, түйіндердің құлауы, тұтынушының артта қалуы → SLO шеңберінде қалады.
CI-дегі Smoke: уақытша тақырыптағы қысқа end-to-end пайплайн.
13) «CRUD-интеграция → EDA» көші-қоны
1. Домендік деректерді сәйкестендіріңіз.
2. outbox бағдарламасын бастапқы сервистерге енгізіңіз.
3. Ең аз домендік оқиғаларды жариялап, 1-2 проекцияларды қосыңыз.
4. Ілеспе нүктелерді жазылымдармен ауыстыру арқылы оларды біртіндеп өшіріңіз.
5. Schema Registry және сыйысымдылық саясатын енгізіңіз.
6. Оқиғаларды add-only өрістерімен кеңейтіңіз; сындыру - тек жаңа түрлер арқылы.
14) Қарсы үлгілер
Оқиғалар = «DTO API» (тым қалың, ішкі модельге байланысты) - тұтынушыларды бұзады.
Schema Registry және үйлесімділіктің болмауы - «нәзік» интеграция.
Кодтан жариялау және ДБ-ға жазу атомарлы емес (outbox жоқ) - оқиғаларды жоғалтасыз.
«Exactly-once барлық жерде» - пайдасыз жоғары баға; at-least-once + іспеттілік жақсы.
Бір «әмбебап» партияландыру кілті → ыстық партиция.
Реплика тікелей прод-проекцияға - онлайн SLO-ны бұзады.
15) Енгізу чек-парағы (0-45 күн)
0-10 күн
Домендік оқиғаларды және олардың кілттерін (реттік түйіршіктер) анықтау.
Schema Registry бағдарламасын кеңейтіп, үйлесімділік стратегиясын бекіту.
1-2 сервистерге outbox/inbox қосу; ең аз CloudEvents-envelope.
11-25 күн
retry/DLQ, backoff, өңдегіштердің теңсіздігін енгізу.
Дашбордтар: lag/age/end-to-end; burn-rate алерта.
Оқиғалар құжаттамасы (каталог), owner's және схемаларды тексеру процестері.
26-45 күн
Бірінші проекцияның репликасы/қайта құрылуы; runbook репликасы мен backfill.
Қауіпсіздік саясаты (TLS, ACL, PII), ретеншн, GDPR-процедуралар.
Брокер және тұтынушылар үшін тұрақты chaos-және game-days.
16) Жетілу метрикасы
Домендік оқиғалардың 100% схемалармен сипатталған және тіркелген.
Outbox/inbox Tier-0/1 барлық продюсерлерін/консьюмерлерін қамтиды.
SLO: p95 end-to-end latency және consumer lag мақсаттар шегінде ≥ 99%.
Реплика/Backfill даунтайсыз жүзеге асырылуы мүмкін; тексерілген runbook 'ы бар.
Нұсқалау: жаңа өрістер - сынықсыз; ескі тұтынушылар құлдырамайды.
Қауіпсіздік: TLS + mTLS, ACL per topic, кіру журналдары, PII/ретеншн саясаты.
17) Шағын сниппеттер
Kafka Producer (сенімді жарияланым, идеялар):properties acks=all enable.idempotence=true max.in.flight.requests.per.connection=1 compression.type=zstd linger.ms=5
Consumer-өңдегіш (іспеттестік, жалған құжат):
python if inbox.contains(event_id): return # дедуп process(event) # побочные эффекты детерминированы inbox.commit(event_id) # atomically with side-effect commit_offset()
DLX (идея) арқылы RabbitMQ Retry:
- `queue: tasks` → on nack → DLX `tasks. retry. 1m '(TTL = 60s) → қайтару' tasks '; әрі қарай '5m/15m'.
18) Қорытынды
EDA интеграцияны нақты келісімшарттар мен басқарылатын келісімділікпен бизнес-фактілер ағынына айналдырады. Іргетас қалаңыз: схемалар + тізілім, outbox/inbox, тәртіп кілттері, демпотенттік өңдегіштер, SLO және бақылау, қауіпсіз ретеншн және реплика. Сонда оқиғалар сіздердің «ақиқат көзіңізге» айналады.