🧑🎓Объяснение:
✅ Почему модульный монолит — оптимальный выбор:
1. Скорость разработки (Time-to-Market)
В монолите всё работает «в одном процессе»: вызовы между модулями — это просто вызовы функций, а не HTTP-запросы. Не нужно тратить время на:
Проектирование и версионирование API между сервисами
Настройку сетевого взаимодействия и балансировщиков
Обработку таймаутов и повторных попыток
Сериализацию/десериализацию данных
Для команды из 5 человек это означает, что первую версию продукта можно выпустить за 1-2 месяца, а не за полгода. В стартапе это часто вопрос выживания.
2. Простота разработки и тестирования
Одно приложение легче:
Собрать и запустить локально у каждого разработчика
Покрыть интеграционными тестами (не нужно поднимать окружение из 5+ сервисов)
Отлаживать (дебаггер работает сквозь все слои)
Деплоить (один артефакт, одна команда деплоя)
3. Модульность внутри монолита — залог будущего
«Модульный монолит» — это не свалка кода, а чётко организованная структура:
Выделение бизнес-модулей (курсы, пользователи, оплата, уведомления)
Строгое разделение слоёв (контроллеры → сервисы → репозитории)
Чёткие интерфейсы между модулями внутри кода
Это позволяет в будущем «вырезать» модуль в отдельный микросервис, если:
Модуль требует независимого масштабирования (например, видео-сервис)
Команда выросла и нужно разделить ответственность
Появились специфические требования к технологиям (например, для видео нужен Go, а для оплаты — Java)
4. Экономия ресурсов
Пока у стартапа нет миллионной нагрузки, платить за инфраструктуру для микросервисов (балансировщики, несколько баз данных, оркестрация) — просто выбрасывать деньги. Монолит можно крутить на одном небольшом сервере за $50/мес.
❌ Почему другие варианты не подходят:
A) Микросервисная архитектура
Микросервисы — это распределённая система, со всеми вытекающими сложностями:
Сетевое взаимодействие — любой вызов может упасть с таймаутом, нужно реализовывать retry, circuit breaker
Распределённые данные — сложно делать JOIN между таблицами разных сервисов, нужны саги или паттерн CQRS
DevOps-нагрузка — нужно настроить CI/CD для каждого сервиса, мониторинг, логирование, трассировку
Когнитивная нагрузка — разработчики должны держать в голове всю картину взаимодействий
Для 5 человек и MVP это неподъёмно. Микросервисы — это про организационную масштабируемость, а не про техническую. Конвей Глиз (C. Hale) говорил: «Микросервисы — это то, что вы делаете, когда ваша команда выросла настолько, что монолит мешает её организации».
C) Серверлесс (FaaS)
Serverless (AWS Lambda, Google Cloud Functions) хорошо подходит для:
Обработки событий (загрузили файл — запустилась функция)
Микросервисов с чёткой единичной ответственностью
Проектов с непредсказуемой, скачкообразной нагрузкой
Но для целого приложения с множеством взаимосвязанных функций serverless создаёт проблемы:
Холодный старт — если функции долго не вызывались, первый пользователь будет ждать 1-3 секунды
Vendor lock-in — логика привязывается к конкретной облачной платформе
Сложность отладки — трудно воспроизвести распределённый сценарий локально
Ограничения по времени выполнения — большинство функций не могут работать дольше 15 минут
MVP платформы онлайн-курсов требует целостного приложения с сессиями пользователей, сложными транзакциями — serverless здесь неудобен.
D) Событийно-ориентированная архитектура
Event-driven архитектура (через Kafka, RabbitMQ) отлично подходит для:
Слабосвязанных систем
Асинхронных процессов (уведомления, аналитика)
Интеграций между командами
Но для MVP это избыточно:
Сложность понимания потоков данных (событие может обрабатываться несколькими подписчиками в неизвестном порядке)
Eventual consistency — данные не согласованы мгновенно, что может сбивать с толку пользователей
Нужна инфраструктура для брокера сообщений
Для простого сценария «купил курс — получил доступ» можно обойтись синхронным вызовом в монолите, не усложняя систему.