Почему казино переходят на модульную архитектуру
Зачем казино модульность
Исторический монолит тормозит рост: каждое изменение тянет релиз всей системы, интеграции провайдеров и PSP бьют по SLO, комплаенс-апдейты — по всему коду. Модульная архитектура (domain-driven + контрактные API + события) позволяет:- Быстро выводить фичи и подключать провайдеров без координации «всех со всеми»;
- Масштабировать избирательно (live-видео отдельно от кассы, кошелёк отдельно от каталога игр);
- Изолировать риски (ошибка в промо не валит кошелёк);
- Соблюдать лицензии (логирование/версии/политики в доменных границах);
- Снизить TCO за счёт чётких контрактов, повторного использования и автоматизации.
Карта доменов (пример разбивки)
Wallet/Ledger — деньги, хедж валют, бонусные балансы, PITR, аудит.
Cashier/Payments — PSP, он-рамп/офф-рамп, KYT, идемпотентные вебхуки.
Gaming Bridge — адаптеры провайдеров, нормализация round/bet.
Catalog/Lobby — игры, провайдеры, фичеринг и правила показа.
Promo/Bonus — правила акций, ваучеры, wager.
KYC/AML/RG — проверка личности, санкции/PEP, лимиты и самоисключение.
Experience — фронтенд, CDN, i18n, A/B, Telegram WebApp.
Telemetry/Analytics — события, витрины, ML/ИИ.
Compliance & Audit — отчёты MGA/UKGC, WORM-архив.
Принципы модульной архитектуры
1. DDD-границы (bounded context). Чёткое владение данными и логикой.
2. API-первый + события. OpenAPI/AsyncAPI, JSON-Schema, контрактные тесты.
3. Версионирование и совместимость. `v1 → v1.1 → v2` (expand→migrate→contract).
4. Idempotency & Exactly-once-intent. Ключи запросов, дедупликация событий.
5. Безопасность по умолчанию. mTLS, HMAC-подписи, короткие JWT, RBAC/ABAC.
6. Независимые релизы. Канареечный/blue-green деплой, миграции «двухписателем» запрещены.
7. Наблюдаемость. Сквозной `traceId`, метрики SLO на модуль.
8. Фича-флаги. Трафик/гео/юзер-сегменты, безопасные откаты.
Слой интеграций: как подключать провайдеров и PSP
Adapter/Bridge-паттерн: каждый провайдер игр/платежей — плагин с единым контрактом платформы.
Игры: нормализация `roundId/betId/status`, маппинг ошибок, кеш лимитов.
Платежи: единый интерфейс `authorize/capture/refund/payout`, вебхуки с идемпотентностью.
Отключаемость: неисправный адаптер переводится в maintenance без влияния на другие.
Пример контракта (фрагмент OpenAPI):yaml post /wallet/debit:
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/DebitRequest@v1'
responses:
'200': { $ref: '#/components/schemas/DebitResult@v1' }
'409': { description: IDEMPOTENT_REPLAY }
События как «кровеносная система»
Шина (Kafka/NATS) → события:- `bet.placed`, `round.settled`, `payout.requested/approved`, `kyc.verified/failed`, `rg.limit_set`, `bonus.issued/consumed`, `cashier.webhook.received`, `wallet.hold/release`, `alert.slo_breach`.
- События не отменяют прошлое; корректировки — отдельными компенсирующими событиями.
- Каждый модуль пишет только свои исходные события, производные — как новые темы.
Данные: слои и согласованность
OLTP на модуль: Postgres/MySQL/KeyDB — изолированные транзакции.
OLAP/витрины: ClickHouse/BigQuery строятся из событий; OLTP и аналитику не смешиваем.
Feature Store/ML: независимый от OLTP слой с версиями фич и TTL.
Согласованность: стратегически eventual между модулями, а для денег — локальные ACID + идемпотентные действия на границах.
Деплой и масштабирование
Контейнеры (Docker/K8s): автоскейл по модулю (wallet — CPU/IO; live-видео — сеть; bridge — RPS).
Изоляция периметра: сетевые политики, отдельные секреты/ключи на модуль, разные хранилища PII/денег/телеметрии.
Трафик-шейпинг: фича-флаги, канареечная доля, региональные маршруты.
DR/HA: Multi-AZ; актив-пассив для денег, актив-актив для чтений/медиа.
Комплаенс «вшит» в модули
KYC/AML/RG — собственный модуль с политиками и журналом решений (`policyVer`).
Audit/WORM — неизменяемое хранилище событий денег/раундов/выплат.
Отчётность — экспорт по юрисдикциям (MGA/UKGC), SLA на полноту/своевременность.
Образец потоков
Ставка → расчёт → выплата
1. `gaming-bridge` отправляет `bet.placed` (idempotent).
2. `wallet` делает `hold` и публикует `wallet.hold`.
3. `gaming-bridge` получает результат провайдера → `round.settled`.
4. `wallet` считает `settle` (release/payout) → `wallet.settled`.
5. `promo` потребляет события и начисляет бонус → `bonus.issued`.
Касса (депозит)
1. `cashier` создаёт `payment.intent` с `Idempotency-Key`.
2. PSP зовёт вебхук → `cashier.webhook.received`.
3. `wallet.credit` по факту → событие для аналитики и RG.
Изменения без простоя (expand→migrate→contract)
1. Expand: добавили поля/эндпоинт в `v1.1`, старые клиенты не ломаются.
2. Migrate: потребители читают новое, пишут в обе версии (dual-write только для не-денежных).
3. Contract: объявили EOL `v1.0`, удалили через N недель по плану.
Платформенная инженерия
Golden Paths: шаблоны модулей (repo-аскелеон, CI/CD, алерты, SLO, секреты).
Контрактные тесты: Pact/AsyncAPI tests в CI; среда интеграций с фейк-провайдерами.
Каталог сервисов (Backstage): кто владелец, SLA, версии API, инцидент-рукбуки.
Метрики успеха модульности
Lead time от идеи до прод-релиза ↓ в X раз.
Частота релизов по модулю ↑ (в день/неделю), change-fail rate ↓.
MTTR по инцидентам ↓ (из-за изоляции).
Infra cost / GGR стабилен или ↓ при росте трафика (избирательный скейл).
Время интеграции провайдера/PSP (от брифинга до прод) ↓.
Анти-паттерны
«Микросервисы ради микросервисов». Без чётких границ данных растёт связность и сложность.
Общие БД/схемы между модулями. Убивает изоляцию и независимые релизы.
События без версии/контракта. Ломают потребителей «тихо».
Dual-write для денег. Риск несогласованности — только идемпотентные шаги через один писатель.
Глобальный «утилити-слой» со всем подряд. Превращается в скрытый монолит.
Нет фича-флагов и kill-switch. Любая ошибка сразу бьёт по всем.
Смешение OLTP/OLAP. Отчёты тормозят ставки/кошелёк.
Без наблюдаемости. Нечем измерить SLO и связывать инциденты.
Чек-лист перехода на модульную архитектуру
Стратегия и домены
- Определены bounded contexts, владельцы и KPI по модулю.
- Карта взаимодействий: API/события, критичность и SLO.
Контракты и безопасность
- OpenAPI/AsyncAPI + JSON-Schema; версия и жизненный цикл.
- mTLS/HMAC, короткие JWT, RBAC/ABAC на границах.
Данные
- Разделённые OLTP; события — источник для OLAP.
- Idempotency на API/вебхуках, дедупликация сообщений.
CI/CD и релизы
- Канарейка/blue-green, фича-флаги, автоскейл по модулю.
- Контрактные тесты в CI; среда с фейк-провайдерами.
Наблюдаемость
- Логи/метрики/трейсы с `traceId`; SLO-дашборды.
- Алерты по бизнес-метрикам (VOID, reject, payout lag).
Комплаенс
- WORM-архив денег/раундов, экспорт регуляторной отчётности.
- KYC/AML/RG как отдельный модуль с журналом решений.
Мини-примеры
Событие `round.settled@v1`:json
{
"event":"round.settled", "v":"1", "roundId":"R-2025-10-17-evo-23", "gameId":"evo_blackjack_23", "bets":[{"betId":"b_92f","playerId":"p_1","stake":"10.00","payout":"15.00","outcome":"WIN"}], "ts":"2025-10-17T14:23:13.120Z", "traceId":"tr_5f1"
}
Идемпотентный кошелёк:
http
POST /wallet/settle
X-Idempotency-Key: 9a7f-2b1c
{
"roundId":"R-2025-10-17-evo-23", "operations":[{"playerId":"p_1","delta":"5.00","currency":"EUR"}]
}
Модульная архитектура превращает казино-платформу из «хрупкого комбайна» в композицию надёжных доменов: каждый со своими контрактами, данными и SLO. Это ускоряет интеграции и релизы, даёт избирательное масштабирование, упрощает комплаенс и снижает риски инцидентов. Начните с выделения доменных границ, контрактов и событий, «вплетите» безопасность и наблюдаемость — и вы получите платформу, которая растёт вместе с продуктом, а не тормозит его.