Пока рынок не найден, архитектура SaaS должна быть дешёвой в изменении: модульный монолит, общая база с идентификатором арендатора в каждой строке, проверка доступа на сервере и в базе, конфигурация в окружении. Заранее принимайте только решения, которые дорого развернуть позже, — модель арендаторов, способ аутентификации, экспорт данных клиента и журнал архитектурных решений; остальное откладывайте до появления реальной нагрузки и платящих клиентов.
Содержание
- Главный критерий — стоимость изменения, а не масштаб
- Модель арендаторов: общие, выделенные или смешанные ресурсы
- Модульный монолит вместо микросервисов
- Что заложить с первого дня
- Что сознательно отложить — и по какому сигналу вернуться
- Как оформить решения, чтобы их можно было пересмотреть
- Когда нужен взгляд со стороны
Главный критерий — стоимость изменения, а не масштаб
До того как продукт нашёл рынок, вы не знаете главного: какие функции будут нужны, кто будет платить и в каком объёме. Архитектура, рассчитанная на миллион пользователей, в этот момент — ставка на будущее, которого может не быть. Мартин Фаулер в заметке «Monolith First» формулирует это через вопрос: когда вы начинаете новое приложение, насколько вы уверены, что оно будет полезно пользователям? Пока уверенности нет, скорость обратной связи важнее масштабируемости.
Практический вывод — разделить решения на два типа. Одни легко поменять через полгода: выбор кэша, очереди, библиотеки интерфейса. Другие тянут за собой данные и клиентов: если ошибиться, исправление потребует миграции всех арендаторов или повторной регистрации пользователей. Время до инвестиций стоит тратить на вторые.
Модель арендаторов
- Цена ошибки позже
- Высокая: затрагивает схему данных, доступы и всех клиентов
- Что сделать сейчас
- Определить, кто такой арендатор, и заложить его идентификатор везде
Аутентификация
- Цена ошибки позже
- Высокая: смена провайдера означает перенос учётных записей
- Что сделать сейчас
- Взять проверенный провайдер или библиотеку, не писать своё
Схема ключевых сущностей
- Цена ошибки позже
- Средняя или высокая: миграции на живых данных
- Что сделать сейчас
- Продумать идентификаторы и связи для двух-трёх главных сущностей
Разбиение на сервисы
- Цена ошибки позже
- Низкая, если границы модулей чистые
- Что сделать сейчас
- Отложить, держать модули внутри одного приложения
Облачный провайдер
- Цена ошибки позже
- Средняя
- Что сделать сейчас
- Держать конфигурацию в окружении, не завязываться на уникальные сервисы без причины
Модель арендаторов: общие, выделенные или смешанные ресурсы
Арендатор (tenant) — это тот, чьи данные должны быть отделены от других. В B2B это обычно компания-клиент со своими сотрудниками; в B2C — человек, семья или группа. Руководство Microsoft по многоарендным решениям подчёркивает: выбор модели — не только техническое, но и коммерческое решение, потому что он определяет себестоимость клиента, требования к соответствию и то, что вы сможете продавать.
Общие ресурсы (pool)
- Как устроена
- Одно приложение и одна база, в каждой строке — идентификатор арендатора
- Плюсы
- Дешевле всего в эксплуатации, одно обновление для всех
- Минусы
- Ошибка в проверке доступа может открыть чужие данные; тяжёлый клиент влияет на остальных
Выделенные ресурсы (silo)
- Как устроена
- Отдельная база или вся инфраструктура на клиента
- Плюсы
- Сильная изоляция, проще требования регуляторов
- Минусы
- Стоимость растёт с каждым клиентом, обновления нужно катить на все копии
Смешанная (bridge)
- Как устроена
- Часть компонентов общая, часть выделена
- Плюсы
- Можно выделить крупного или регулируемого клиента
- Минусы
- Код должен поддерживать оба режима
Термины pool, silo и bridge взяты из SaaS Lens AWS Well-Architected; Microsoft описывает те же варианты как полностью многоарендное, вертикально и горизонтально разделённое развёртывание. Для раннего B2B-продукта рабочий выбор по умолчанию — общие ресурсы с идентификатором арендатора и проверкой доступа в двух местах: в коде приложения и в базе. В PostgreSQL второй рубеж дают политики Row Level Security: после их включения доступ к строкам запрещён, пока политика его явно не разрешит. Важная деталь из документации: владелец таблицы обычно обходит эти политики, если не включить FORCE ROW LEVEL SECURITY.
Какую бы модель вы ни выбрали, её нужно проверять тестами: пользователь одного арендатора не должен получить данные другого ни через интерфейс, ни через API. Microsoft отдельно рекомендует тестировать модель изоляции, а не полагаться на то, что она «заложена в архитектуре».
Модульный монолит вместо микросервисов
Фаулер отмечает, что почти все успешные истории микросервисов начинались с монолита, который стал слишком большим и был разделён. Причина простая: до поиска рынка вы не знаете, где на самом деле проходят границы предметной области, а переносить границу внутри одного приложения намного дешевле, чем между отдельно развёрнутыми сервисами со своими базами и контрактами.
Модульный монолит — это одно развёртываемое приложение, разделённое на модули по бизнес-возможностям: биллинг, пользователи и доступы, основной сценарий продукта, уведомления. Модули обращаются друг к другу через явные интерфейсы, а таблицы в базе принадлежат конкретному модулю. Когда появится реальная причина выделить сервис — отдельная команда, иной профиль нагрузки, требования к изоляции, — граница уже будет нарисована.
Модульный монолит сейчас
- Одна сборка, один деплой, одна база
- Изменение сквозной функции — одна задача
- Отладка в одном процессе
- Небольшой команде не нужна отдельная платформа
Микросервисы сейчас
- Сетевые вызовы, версии контрактов, распределённые сбои
- Сквозное изменение затрагивает несколько сервисов
- Нужны трассировка и общая наблюдаемость с первого дня
- Границы зафиксированы раньше, чем понятен продукт
Что заложить с первого дня
Этот список не требует большой команды. Каждый пункт дёшев в начале и дорог, если добавлять его в продукт с живыми клиентами.
- Идентификатор арендатора в каждой таблице с данными клиентов и тесты, которые проверяют изоляцию.
- Аутентификация через проверенный провайдер или библиотеку; роли — внутри арендатора, проверка прав — на сервере.
- Конфигурация и секреты — в переменных окружения, а не в коде, как предлагает методология The Twelve-Factor App.
- Разделённые окружения разработки, тестирования и рабочее, максимально похожие друг на друга.
- Изменения схемы базы — миграциями в репозитории.
- Экспорт данных арендатора в понятном формате: его попросят клиенты, а позже — и при проверке перед сделкой.
- Журнал значимых действий: кто и когда изменил права, удалил данные, поменял тариф.
- Резервные копии и проверенное восстановление.
- Журналы приложения как поток событий, который можно искать и анализировать.
- Тарифы и ограничения как данные, а не как условия, разбросанные по коду.
Что сознательно отложить — и по какому сигналу вернуться
Откладывать не значит игнорировать. Хорошая практика — записать для каждого отложенного решения сигнал, при котором к нему нужно вернуться. Тогда отказ от сложности становится осознанным решением, а не пробелом.
Выделение микросервисов
- Сигнал вернуться к решению
- Модулем занимается отдельная команда, или у него принципиально иной профиль нагрузки
Отдельная база на каждого клиента
- Сигнал вернуться к решению
- Клиент требует изоляции по договору или регулятору, либо один арендатор заметно мешает остальным
Несколько регионов размещения
- Сигнал вернуться к решению
- Требования к месту хранения данных или задержкам у реальных клиентов
Собственный биллинговый движок
- Сигнал вернуться к решению
- Тарифная модель перестала укладываться в возможности платёжного провайдера
Шардинг и сложное кэширование
- Сигнал вернуться к решению
- Измеренные узкие места на реальной нагрузке, а не прогноз
Kubernetes и собственная платформа
- Сигнал вернуться к решению
- Число сервисов и окружений, которое команда уже не может обслуживать проще
Как оформить решения, чтобы их можно было пересмотреть
Через год никто не вспомнит, почему выбрали именно эту модель арендаторов или этот провайдер аутентификации, — а именно эти вопросы зададут новый технический руководитель, команда, которая примет продукт, или технический эксперт инвестора. Простой инструмент — запись архитектурного решения (Architecture Decision Record, ADR), формат которой предложил Майкл Найгард.
- Название — короткая фраза: «Общая база с идентификатором арендатора».
- Контекст — какие силы и ограничения действовали: число клиентов, требования, команда, сроки.
- Решение — что решили, в активном залоге.
- Статус — предложено, принято, устарело или заменено другим решением.
- Последствия — все, не только положительные: что стало проще, что сложнее, какой сигнал заставит пересмотреть.
Записи хранятся в репозитории рядом с кодом, нумеруются по порядку, номера не переиспользуются. Если решение пересмотрели, старую запись не удаляют, а помечают как заменённую и ссылаются на новую. Десяток таких записей объясняет архитектуру лучше, чем большой документ, который перестал совпадать с кодом.
Когда нужен взгляд со стороны
Разовая консультация полезнее всего в трёх точках: перед выбором модели арендаторов и схемы ключевых сущностей; когда первый крупный клиент просит изоляцию или особые условия хранения данных; и перед привлечением инвестиций, когда нужно убедиться, что архитектура и записи решений выдержат вопросы технического эксперта. Во всех трёх случаях полезно прийти с брифом: что делает продукт, кто арендатор, какие интеграции и данные, какие ограничения.


