• modular monolith
  • microservices
  • domain design
  • platform architecture

Модульный монолит или микросервисы: какие границы нужны iGaming-платформе

Модульный монолит или микросервисы: какие границы нужны iGaming-платформе

Сравните независимость релизов, согласованность финансовых операций, масштабирование и стоимость эксплуатации. Пример со ставкой и кошельком, план выделения сервиса и четыре приёмочные проверки помогут принять обоснованное архитектурное решение.

У казино-платформы могут быть отдельные API кошелька, игр и бонусов, но для изменений ей всё равно может требоваться согласованный релиз и общее изменение базы данных. И наоборот: одно развёртываемое приложение может содержать чётко выделенные предметные области, которые удобно тестировать и поддерживать. Количество сервисов не показывает, какую платформу проще менять и безопаснее эксплуатировать.

Полезнее задать более узкий вопрос: какая граница устранит подтверждённое ограничение и какие новые состояния отказа она создаст? Для технического директора, архитектора или руководителя разработки ответ должен связывать бизнес-проблему с решением, которое можно внедрить. В этом руководстве мы проследим путь ставки через такую границу, а затем разберём выбор и проверку первого выделяемого компонента. Конкретное облако, фреймворк или порог нагрузки не предполагаются.

Различайте модульность и независимость развёртывания

Модульный монолит — приложение, развёртываемое как единое целое, с внутренними границами между функциями. Микросервис — отдельно развёртываемая функция с явным контрактом и полномочиями в отношении собственных данных. Отдельные репозитории или контейнеры сами по себе не доказывают, что сервис можно выпускать без согласованных изменений в остальных компонентах.

В модульной платформе определите интерфейсы кошелька, ставок, платежей и бонусов, разрешённые зависимости и ответственность за записи. Не допускайте прямого изменения таблиц кошелька другим модулем; общая транзакция при этом может координировать работу через эти интерфейсы. Закрепляйте границы проверками зависимостей, ревью кода и тестами. Иначе слово «модульный» описывает лишь структуру папок.

Для отдельных сервисов контракты должны работать через сеть: вызывающая сторона может не дождаться ответа, версии могут сосуществовать, а результат удалённой операции — оставаться неизвестным. Сервис может логически владеть данными при общей инфраструктуре базы, но общие ресурсы и отказы сохраняют зависимости. Владение хранилищем и физическая изоляция — разные решения. В материале о ключевых доменах и их границах подробно рассмотрена модель ответственности; здесь вопрос в том, оправдывает ли перенос границы за пределы процесса свою стоимость.

Проследите путь ставки через границу транзакции

Рассмотрим условную платформу, которая принимает ставку, используя собственные записи кошелька и ставок. Если обе записи участвуют в одной транзакции базы данных, приложение может вместе зарезервировать доступные средства при выполнении нужных условий и создать запись ставки. При этом необходимы правила конкурентного доступа и стабильный идентификатор запроса. Общая база сама по себе не мешает двум одновременным запросам потратить один и тот же остаток. Принятие ставки сторонним провайдером или внешний платёж находятся за пределами этой локальной транзакции.

Теперь перенесём кошелёк в отдельный сервис. Возможная последовательность: сохранить незавершённый запрос, зарезервировать средства с его стабильным идентификатором операции, зафиксировать результат принятия ставки, затем завершить резервирование по согласованному контракту. Точный момент принятия зависит от продукта и провайдера. Прежде чем одобрить разделение, выясните, что произойдёт, если кошелёк зафиксирует резерв, но ответ потеряется, или если вызывающая сторона перезапустится до сохранения следующего шага.

  • Результат резервирования неизвестен: восстановите существующую операцию по идентификатору либо повторите запрос по контракту, возвращающему её прежний результат. Привяжите идентификатор к исходному запросу и отклоняйте изменённые параметры. Не создавайте новое списание лишь потому, что вызывающая сторона не дождалась ответа.
  • Подтверждённый отказ до принятия ставки: освободите подтверждённый резерв через сохраняемую операцию, которую можно безопасно повторять.
  • Ставка уже могла быть принята: сохраняйте видимый незавершённый случай до выяснения результата. Истечение времени ожидания само по себе не даёт оснований освобождать деньги, которые могут обеспечивать принятую ставку. Истечение срока резерва тоже должно учитывать эту неопределённость; автоматический таймер освобождения не заменяет выяснение результата.
  • Одновременные запросы: кошелёк должен обеспечивать соблюдение правил расходования при обновлении данных, за которое отвечает сам кошелёк; закешированный баланс вызывающей стороны не может разрешать резервирование.

Это требования к рассматриваемому примеру, а не универсальный протокол провайдеров. В руководстве AWS по сагам отмечено, что координация локальных транзакций приводит к согласованности с задержкой и не обеспечивает изоляцию транзакций. Компенсации нужны собственные правила; это не откат транзакции базы данных сразу во всех сервисах. Если команда не может объяснить каждое промежуточное финансовое состояние, сохраняйте локальную границу, пока этот вопрос не решён.

Определите ограничение, которое действительно устранит сервис

Запишите симптом прежде, чем предлагать сервис. Формулировка «платформа медленная» слишком общая. Отчёт может конкурировать с записью операций кошелька за ресурсы базы; обработка изображений — занимать процессор приложения; интеграция провайдера — задерживать релиз, поскольку все изменения выпускаются вместе. Это разные ограничения.

  • Ресурсоёмкая фоновая задача: сначала проверьте отдельный обработчик с выделенным ресурсным бюджетом или модель данных для чтения. Обработчик можно масштабировать независимо, не превращая каждый домен в сервис; перенос работы в другой процесс меняет эксплуатацию даже при общей кодовой базе.
  • Финансовая запись с высокой конкуренцией за доступ: измерьте ожидание блокировок, изучите планы запросов и конкурентную запись. Добавление сетевого вызова к тому же последовательному обновлению не повышает пропускную способность этого обновления.
  • Зависимость между релизами: определите контракт или изменение базы, требующие согласования. Раздельное развёртывание помогает только тогда, когда потребители могут продолжать работать с поддерживаемым контрактом.
  • Распространение отказа одной интеграции: сначала ограничьте число одновременных операций, очередь и потребление ресурсов. Отдельный процесс может улучшить локализацию, но синхронные зависимости и общая инфраструктура всё ещё способны передавать отказ дальше.

Зафиксируйте исходные показатели с помощью метрик процессов, логов и трассировок. Сравните одинаковую репрезентативную нагрузку до и после изменения. Учитывайте завершённые операции, время ожидания и трудозатраты на восстановление, а не только процессорную нагрузку или успешные HTTP-ответы. Выделение обоснованно, если оно снимает заявленное ограничение, не скрывая незавершённую работу в очереди.

Сравнивайте варианты по доказательствам, а не по баллам

Используйте следующие вопросы для выбора решения. Они намеренно не дают взвешенного «победителя»: недопустимое финансовое состояние нельзя компенсировать более быстрым развёртыванием.

  • Стабильность границы: часто ли бизнес-правила переходят между предполагаемыми компонентами? Изучите недавние изменения и ближайшие известные требования продукта. Частое перемещение правил — довод в пользу внутренней границы, которую проще пересматривать.
  • Согласованность: какие записи должны меняться вместе, а какие потребители данных допускают задержку? Разберите истечение времени ожидания после каждого зафиксированного шага. Сохраняйте тесно связанные обновления вместе, если нет обоснования для полностью спроектированного распределённого процесса.
  • Независимость релизов: может ли ответственная команда выпустить совместимое изменение, пока потребители остаются на текущей версии? Покажите это тестом контракта и репетицией, а не новым репозиторием.
  • Масштабирование или локализация: можно ли отделить ограничивающий ресурс? С помощью профилирования и учения с отказом покажите, что изоляция компонента улучшает нужный пользовательский процесс.
  • Ответственность за эксплуатацию: кто отвечает за оповещения, обновления, восстановление и вывод контрактов из использования? Даже независимое развёртывание требует команды, способной поддерживать его после ухода первоначального разработчика.
  • Полная стоимость: оцените разработку, миграцию и параллельную работу, а затем регулярные затраты на инфраструктуру, телеметрию, поддержку безопасности, разбор инцидентов и сверку. Сравните их с измеренной стоимостью текущего ограничения и более простого варианта.

В Monolith First Мартин Фаулер на основе опыта обосновывает совместный старт при неопределённых границах. Он также рассматривает старт с крупными сервисами. Это аргументы для проектирования, а не универсальное правило; выбирайте по возможностям и ограничениям, которые команда может подтвердить.

Проверьте независимость изменений и локализацию отказов

Изучите три признака связанности: потребитель должен развёртываться при каждом изменении зависимости; несколько сервисов могут менять одну бизнес-запись без единого ответственного источника; недоступность одного сервиса мешает завершить процесс, в остальном с ним не связанный. Переименование компонентов не решает ни одну из этих проблем.

Отрепетируйте совместимый релиз при одновременной работе старых и новых потребителей. Добавьте новое поле или поведение, не требуя немедленного перехода потребителей. Переведите потребителей и проследите использование прежнего контракта, прежде чем требовать новое поведение или прекращать прежнюю поддержку. Применяйте ту же последовательность к изменениям схемы. Изменения данных из других сервисов должны идти через контракт владельца; права доступа к базе должны поддерживать эту модель полномочий. Общая модель для чтения может помогать отчётности, но не должна становиться ещё одним источником финансовой записи.

Затем отключите зависимость. Определите, какие операции можно надёжно сохранить для ожидания, какие допускают явно ограниченное устаревшее представление, а какие нужно остановить из-за недоступности компонента, уполномоченного принимать решение. Для отчётности может быть допустима согласованная задержка; закешированный отчёт не должен незаметно превращаться в разрешение на ставку или вывод средств. Ограничьте ожидающую работу и проверьте поведение при достижении лимита.

В Microservice Prerequisites Фаулер выделяет автоматизацию развёртывания, мониторинг и совместную ответственность разработки и эксплуатации. Продемонстрируйте эти возможности до увеличения числа сервисов. Они полезны и монолиту. Разберите реальный путь инцидента: кто его замечает, что позволяет определить затронутые операции и кто может безопасно их восстановить?

Выделите одну функцию без конкурирующих источников записи

Предположим, что кандидат на выделение — отчётность, поскольку аналитические запросы мешают обработке транзакций. Сначала определите исходные записи отчёта, допустимую задержку обновления и способ сверки. Убедитесь, что эта функция отчётности не принимает решения о допуске пользователя или финансовых операциях. Создайте модель для чтения, не меняя компонент, отвечающий за запись исходных данных. Измерьте, перестали ли новые запросы конкурировать за ограничивающий ресурс; реплика или отдельное хранилище могут помочь, но перенос той же дорогой работы в другое общее узкое место может оказаться бесполезным.

Для публикации зафиксированных изменений руководство AWS по транзакционному outbox описывает сохранение записи и исходящего события в одной транзакции с последующей отдельной публикацией. Оно также предупреждает о повторной доставке. Это закрывает локальный разрыв между базой и сообщением, но не делает все эффекты потребителей атомарными и не устраняет задержки доставки.

Для пилота сохраните идентификаторы и порядок, необходимый для каждой записи. Если это возможно, пусть потребитель фиксирует обработку сообщения и своё локальное обновление вместе. Опишите, как он перестраивает данные, догоняет источник и обнаруживает пропущенные изменения. Задайте ресурсный бюджет для outbox и накопившейся работы у потребителей, а также поведение на случай, если длительная недоступность доставки исчерпает этот бюджет: асинхронная работа тоже расходует ресурсы. Сравнивайте старые и новые отчёты на одной границе данных; иначе обычная задержка репликации может выглядеть как ошибка миграции. Не допускайте внешних платежей и других повторных побочных эффектов при теневой обработке.

Если следующее выделение переносит полномочия записи, подготовьте отдельный план переключения: завершите или учтите ещё не завершённые операции, направьте команды одному назначенному владельцу, отключите прежние пути записи и проведите сверку на границе передачи. Сохраните путь восстановления, учитывающий записи после переключения. Возвращать трафик в старую базу небезопасно, если эти изменения есть только в новой. Материал о миграции данных работающей платформы поможет с контролями данных, а руководство по поэтапной модернизации — с выводом старых путей из использования.

Зафиксируйте конкретное решение и проверьте его на пилоте

Завершите работу решением, которое можно предметно оспорить. Зафиксируйте затронутую функцию, текущее ограничение, выбранный вариант, отклонённую простую альтернативу, записи, определяющие достоверное состояние, ответственного, добавленные состояния отказа, объём миграции и доказательства, которые станут поводом для пересмотра. Включите затраты и допущения, неопределённость которых способна изменить выбор.

В условном пилоте отчётности решение может состоять в том, чтобы сохранить запись операций кошелька и ставок вместе, а чтение для отчётности перенести в отдельный обработчик и хранилище. Критерии приёмки — меньшее влияние на обработку транзакций, актуальность отчёта в согласованных пределах, ограниченный объём накопившейся работы и воспроизводимая сверка. Определите нагрузку, интервал измерения, лимит и проверяющего до запуска. Это предлагаемый эксперимент, а не утверждение о клиенте или гарантированном улучшении.

Успешный пилот обосновывает именно эту границу. Он не обосновывает следующее выделение кошелька и не предсказывает оптимальное число сервисов. Если совместимые релизы, восстановление или модель ответственности не проходят проверки ниже, совершенствуйте границу, прежде чем расширять распределённую систему.

Для более широкого обзора материал об архитектуре iGaming-платформы объясняет, как заказать проект, который команда сможет реализовать, а модернизация платформы — как перейти от действующей системы к новой. Используйте их вместе с руководствами по миграции и наблюдаемости, ссылки на которые приведены выше. Прежде чем считать выделение завершённым, потребуйте четыре демонстрации для выбранной границы:

  • Совместимый релиз: разверните выделяемый компонент так, чтобы существующий потребитель продолжал работать. Проверьте период сосуществования версий и покажите, как прежний контракт будет выведен из использования.
  • Локализованный отказ: отключите компонент и проверьте затронутые и незатронутые пользовательские процессы. Покажите ограничение ожидающей работы и согласованное поведение при исчерпании ресурсов; устаревшее представление не должно разрешать финансовое действие.
  • Прерванная операция: выполните перезапуск после фиксации обновления, но до подтверждения. Повторите тот же запрос или событие и восстановите один сохранённый результат без повторных финансовых эффектов. Проверьте видимость незавершённых случаев и ответственность за них.
  • Передача с возможностью восстановления: сверьте обе стороны на одной границе данных и отрепетируйте восстановление с учётом ещё не завершённых операций и изменений после переключения. Подтвердите, какой источник имеет право записи для каждой команды на всём протяжении перехода.
Может ли модульный монолит выдерживать высокую нагрузку?

Он может работать на нескольких экземплярах приложения, если модель состояния и конкурентного доступа поддерживает такую конфигурацию. Реальное ограничение может находиться в базе, одной записи с высокой конкуренцией за доступ или внешнем провайдере. Измерьте ограничивающий ресурс на репрезентативной нагрузке: ни слово «монолит», ни число сервисов не гарантируют пропускную способность.

Какое число разработчиков или запросов оправдывает микросервисы?

Универсального порога нет. Подтвердите стабильность функции, наличие ограничения, которое снимет независимое развёртывание или масштабирование, полноту модели согласованности и способность ответственной команды эксплуатировать компонент. Размер команды и нагрузка — исходные данные для этой проверки, а не её замена.

Нужна ли каждому сервису отдельная физическая база?

Сервису нужны чёткие полномочия в отношении собственных данных и контракт доступа к ним для других компонентов. Физическое разделение — дополнительное решение о ресурсах, безопасности и локализации отказов. Общий сервер базы не требует общих прав записи, но сохраняет инфраструктурные зависимости, которые необходимо признать.

Что делать, если после разделения всё ещё нужен согласованный релиз?

Определите несовместимый контракт, общий путь записи или зависимость схем между сервисами, из-за которых нужно согласование. Исправьте зависимость и отрепетируйте совместную работу старых и новых потребителей. Если независимая эксплуатация не даёт оправданной пользы, оставить функцию модулем может быть понятнее и дешевле.

Проверьте одно архитектурное решение

Опишите проблемный процесс, зависимость между релизами или измеренное узкое место, а также текущего ответственного и порядок восстановления. SPINDO.TECH может оценить предлагаемую границу и определить, какие доказательства нужны для выбора: оставить модуль, отделить фоновый обработчик или выделить сервис.

Инсайты

Инсайты

Как спланировать миграцию данных работающей iGaming-платформы

Как перенести данные работающей iGaming-платформы, сохранив балансы, незавершённые операции и ограничения игроков. Правила преобразования, перенос изменений, сверка, переключение и восстановление.

Как спланировать миграцию данных работающей iGaming-платформы
SPINDO.TECH

14 мин чтения

10 Sep 2026

Наблюдаемость iGaming-платформ: как обнаруживать и расследовать частичные сбои

Постройте мониторинг вокруг результатов для игрока, устойчивого учёта платежей и ставок, полезной трассировки и оповещений, требующих действий. Находите остановившиеся процессы даже при исправном API.

Наблюдаемость iGaming-платформ: как обнаруживать и расследовать частичные сбои
SPINDO.TECH

14 мин чтения

10 Sep 2026

Как модернизировать действующую iGaming-платформу без полного переписывания

Выбирайте первый этап модернизации по реальной проблеме эксплуатации. Выявляйте скрытые правила, определяйте границы замены и отключайте старые пути без конкурирующих полномочий на финансовые операции.

Как модернизировать действующую iGaming-платформу без полного переписывания
SPINDO.TECH

14 мин чтения

10 Sep 2026

Мы используем файлы cookie для обеспечения безопасности и корректной работы нашего сайта. С вашего согласия мы также используем необязательные файлы cookie для аналитики и рекламных целей. Вы можете принять или отклонить использование необязательных файлов cookie. Вы можете изменить свои настройки в любое время. Подробнее — в нашей Политике использования файлов cookie.