Реалтайм-фід подій: архітектура та безпека
Real-time фід подій - це «кровоносна система» продуктів з гейміфікацією, антифродом, CRM-тригерами і виплатами. Щоб він працював передбачувано при піках, не дублював нагороди і не протікав даними, потрібна сувора архітектура: від протоколів і шини до підпису, ідемпотентності, бюджет-каперів і спостережуваності.
1) Цілі та вимоги
Надійність: поставка подій з мінімальним лагом (p95 ≤ 250 мс ingest, p95 ≤ 1-2 с до споживача).
Доставка: at-least-once транспорт + логічна exactly-once через ідемпотентність.
Порядок: впорядкування за ключем (зазвичай'user _ id') з вікнами перевпорядкування.
Безпека: MTLS, HMAC/JWT, ротація ключів, захист від replay/дублікатів, мінімізація PII.
Масштаб: горизонтальний шардинг, backpressure, rate limiting, DLQ/реплей.
Керованість: schema registry, версіонування, міграції без простою.
Комплаєнс: аудит (WORM), RG/KYC гейти, geo-політики, GDPR/анонімізація.
2) Опорна архітектура (шар за шаром)
1. Producers (джерела): ігровий сервер, гаманець/платіжка, KYC/AML, клієнтські SDK (web/iOS/Android).
2. API Gateway (Ingress): прийом HTTP/gRPC, валідація схеми, аутентифікація, HMAC/MTLS, нормалізація часу.
3. Queue/Stream: Kafka/Rabbit/Cloud Pub/Sub - буферизація, партіонування по'user _ id'.
4. Stream Processor: нормалізатор, збагачення, маршрутизація тем, анормалія/антибот прапори, ідемпотентний запис.
5. Consumers: Rules/Scoring, Reward Orchestrator, CRM/CDP конектори, антифрод, аналітичні sink'і.
6. Storage: сирі події (immutable), вітрини, індекс для ідемпотентності, аудит-журнал.
7. Observability: метрики, логи, трасування, алерти; panics → DLQ.
8. Admin Plane: schema registry, ключі/секрети, RBAC/ABAC, фічефлаги, реплей-сервіс.
3) Протоколи доставки: коли що використовувати
HTTP/JSON (server-to-server вебхуки): просто, сумісно, хороший для зовнішніх партнерів. Додати HMAC + ідемпотентність.
gRPC/Protobuf: низька затримка, строгі схеми, bidi-стріми для внутрішніх сервісів.
WebSocket/SSE: push в клієнт, UI-підписки на лідерборди і прогрес.
CDC/Kafka Connect: коли джерела - БД/гаманці, а не бізнес-сервіси.
Рекомендація: зовнішній периметр - HTTP + HMAC + MTLS; всередині - gRPC/Protobuf.
4) Модель події та конвенції
json
{
"event_id": "e_01HF3Z8Z7Q8Q2K", "event_type": "bet", "schema_version": "1. 3. 0", "occurred_at": "2025-10-24T11:37:21Z", "ingested_at": "2025-10-24T11:37:21. 183Z", "key": { "user_id": "u_12345" }, "ctx": {
"session_id": "s_778", "platform": "ios", "geo": "TR", "device_fp": "fp_4a1..."
}, "payload": {
"game_id": "slot_wolf", "bet": 0. 5, "win": 1. 25, "currency": "EUR", "provider": "GameCo"
}, "sig": {
"algo": "HMAC-SHA256", "kid": "k_2025_10", "ts": 1730061441, "mac": "c7b7b3...f1"
}
}
Правила:
- Два часи: 'occurred _ at'( джерело) і'ingested _ at'( шлюз). Допускайте дрейф годинника ± 300 с.
- Ключ маршрутизації - те, що визначає порядок (зазвичай'user _ id').
- PII тільки в'ctx '/' payload'за принципом мінімізації; для чутливих атрибутів - токенізація.
5) Доставка, порядок та ідемпотентність
At-least-once транспорт → можливі дублікати і перевпорядкування.
Exactly-once логіка: тримайте таблицю ідемпотентності з унікальним індексом за «(event_id)» та/або «(user_id, source_seq)»; повтор - no-op.
SQL-скетч:sql
CREATE TABLE event_log (
event_id TEXT PRIMARY KEY, user_id TEXT, event_type TEXT, occurred_at TIMESTAMPTZ, payload JSONB
);
-- вставка з захистом від дублів
INSERT INTO event_log(event_id, user_id, event_type, occurred_at, payload)
VALUES (:event_id,:user_id,:event_type,:occurred_at,:payload)
ON CONFLICT (event_id) DO NOTHING;
Порядок: партиціювання потоку по'user _ id'+ reordering window 60-120 с в процесорі. Пізніше події потрапляють в «перегравання» (replay) коригувальних функцій.
6) Backpressure і управління піками
Token-bucket rate limiting на ingress (per-IP, per-partner, per-key).
Circuit breaker: при 5xx від внутрішніх споживачів → деградація (дропаут необов'язкових подій, черги збільшують ретрай-інтервали).
DLQ: перманентно помилкові повідомлення (бита схема, підпис невалідна, перевищений TTL підпису).
Replay сервіс: вибірковий репабліш з DLQ по'event _ id '/діапазону часу.
7) Схеми та еволюція: як не «зламати» прод
Schema Registry: JSON Schema/Protobuf; політики сумісності: backward для продюсерів, forward для консьюмерів.
Версіонування: 'schema _ version', мажорні - тільки через фічефлаг і подвійний запис (dual-write).
Контракти: просування схеми після канареечного періоду і green metrics.
YAML-приклад правила перевірки:yaml compatibility:
enforce: true mode: backward blocked_fields:
- payload. ssn
- payload. card_number required_fields:
- event_id
- event_type
- occurred_at
8) Модель загроз і захист
Загрози: підміна тіла, повтор (replay), витік PII, компрометація ключа, schema-poisoning, DoS, MITM, сигнатура-stripping.
Захист:- MTLS на периметрі: клієнтські сертифікати з коротким терміном, CRL/OCSP.
- HMAC-підпис тіла +'X-Timestamp'і TTL (± 300 с).
- JWT (client credentials/OAuth2) - для авторизації та обмежень по scope.
- Ротація ключів (KMS): 'kid'у заголовку; план ротації 30-90 днів; подвійна перевірка у вікні міграції.
- Nonce/ідемпотентність: 'X-Request-Id'для запитів-побочок (виплати, бонуси); зберігайте на час TTL.
- Content-Type pinning, max body size, allow-list IP/ASN для критичних інтеграцій.
- WORM-аудит всіх вхідних raw-payload + заголовків (незмінне сховище).
python body = request. raw_body ts = int(request. headers["X-Timestamp"])
assert abs(now() - ts) <= 300 # анти-replay kid = request. headers["X-Key-Id"]
secret = kms. fetch(kid)
mac = hmac_sha256(secret, body)
assert hmac_eq(mac, request. headers["X-Signature"])
9) Приватність, PII і RG/KYC
Мінімізація: PII передавати за посиланням-токеном (на 5-15 хвилин) замість інлайну; редагування/анонімізація в сирих логах заборонені - використовуйте окремі PII-сторанці.
Доступ: ABAC за атрибутами юрисдикції та ролі; всі читання - в аудит-журнал.
GDPR: право на видалення реалізуйте через key-mapping, щоб стерти PII без ломки фактів подій.
RG/KYC: події, що вимагають видачі цінних нагород, пропускайте тільки при валідному KYC-рівні і RG-прапорах «OK».
10) Спостережуваність і SLO
SLO (приклад):- Ingest p95 ≤ 250 мс; end-to-end p95 ≤ 2 с; відмова ≤ 0. 1 %/добу.
- Підпис-помилки (HMAC/JWT) ≤ 0. 02% від загального потоку.
- DLQ fill rate ≤ 0. 1%; «дублікати» після ідемпотентності ≤ 0. 005%.
- RPS за джерелами, p50/p95 latency, 4xx/5xx, підписи-помилки, time-skew.
- Lag по партіях, переробка/сек, fill DLQ, retries, реплей-обсяги.
- Схеми: частка повідомлень за версіями, порушення сумісності.
- Безпека: частота rps-throttle, circuit-breakers, аномалії IP/ASN.
- SRM потоку (різкий перекіс трафіку з одного джерела).
- Латентність p95> цільового 5 хв +, зростання DLQ> X/min.
- Підписи-помилки> Y ppm, сплеск повторів'X-Request-Id'.
- Drift годин> 120 с біля джерела.
11) Мульти-регіон і відмовостійкість
Active-Active регіони, глобальний роутинг (GeoDNS/Anycast), sticky-key по'user _ id'→ регіон.
Крос-регіональний реплікаційний топік для критичних подій (грошові, KYC).
Blast radius: ізоляція за тенантами/брендами, окремі бюджети та ключі.
DR-план: RPO ≤ 5 хв, RTO ≤ 30 хв; Регулярні репетиції.
12) Політики ретеншну і реплея
Сирі події: 7-30 днів (за вартістю), агрегати/вітрини - довше.
Реплей дозволений тільки за підписаним runbook (хто, що, чому, діапазон часу).
Реплей завжди йде в новий stream-version з прапором'replayed = true'для аналітичної прозорості.
13) Приклади конфігурацій
Ingress (NGINX-стиль) ліміти:nginx limit_req_zone $binary_remote_addr zone=req_limit:10m rate=300r/s;
limit_req zone=req_limit burst=600 nodelay;
client_max_body_size 512k;
proxy_read_timeout 5s;
Kafka (приклад):
properties num. partitions=64 min. insync. replicas=2 acks=all retention. ms=604800000 # 7 days compression. type=zstd
Policy для ключів (KMS):
yaml rotation_days: 45 grace_period_days: 7 allow_algos: ["HMAC-SHA256"]
key_scopes:
- topic: "wallet_events"
producers: ["wallet-svc"]
consumers: ["ledger-svc","risk-svc"]
14) Чек-лист запуску real-time фіда
- MTLS на периметрі, HMAC/JWT, ротація ключів ('kid').
- Ідемпотентність на логіці (унікальні ключі, upsert/ON CONFLICT).
- Партіонування по'user _ id', reordering window, реплей-сервіс.
- Schema registry + політики сумісності; dual-write при major-апдейтах.
- Rate limiting, circuit breakers, DLQ + ручний рев'ю.
- Спостережуваність: SLO, алерти по підпису/латентності/DLQ/lag.
- Політика PII/анонімізації, ABAC, аудит WORM.
- DR/мульти-регіон, репетиції фейловера.
- Runbooks: інциденти, реплей, відкат схем/ключів.
15) Міні-кейс (синтетичний)
Контекст: пік турнірів, 120 до RPS ingress, 64 партії, 2 регіони Active-Active.
Разом за 4 тижні: ingest p95 210 мс, e2e p95 1. 6 с; DLQ 0. 05%; підписи-помилки 0. 009%; дублікати після ідемпотентності 0. 003%.
Інцидент: дрейф годинника у партнера (−9 хв) → сплеск anti-replay. Circuit breaker перевів потік в «буферний» ендпоінт, partner-health сповістив CSM; після синку NTP - реплей вікна 12 хв всім консьюмерів. Втрат і подвійних виплат немає.
16) Резюме
Надійний real-time фід - це не «просто вебхукі». Це шарувата система з чіткими контрактами: at-least-once транспорт + логічна exactly-once, схема-регістри і версіонування, MTLS/HMAC/JWT і ротація ключів, backpressure/DLQ/реплей, мінімізація PII і строгий аудит. Дотримуючись цих практик, ви отримаєте швидкий, безпечний і передбачуваний потік подій, на якому можна впевнено будувати гейміфікацію, антифрод, CRM і виплати.