Web-приложения
Архитектура веб-приложения: как выбрать основу продукта
Для большинства новых продуктов безопасная отправная точка — модульный монолит с явными границами, одной основной базой и наблюдаемыми интеграциями. Усложнять архитектуру стоит только под измеримый риск.

Коротко
Архитектуру веб-приложения выбирают по критичным сценариям, нагрузке, данным, интеграциям, требованиям к доступности и возможностям команды. Для MVP обычно достаточно модульного монолита: он дешевле в разработке и эксплуатации. Микросервисы оправданы, когда модули нужно независимо масштабировать, выпускать или изолировать, а команда готова обслуживать распределённую систему.
Карта архитектурного решения до выбора стека
До обсуждения языка и фреймворка команда фиксирует архитектурную карточку. В ней нет декоративной схемы: только ограничения, проверяемые решения и последствия. Такой документ защищает проект от двух крайностей — случайного набора технологий и преждевременных микросервисов.
| Вопрос | Решение для первого релиза | Когда пересматривать |
|---|---|---|
| Границы системы | Модули пользователей, заказов, платежей и отчётов | Когда модуль получает отдельную команду или цикл релизов |
| Источник истины | Одна основная БД; внешние статусы приходят через адаптеры | При появлении независимых контуров данных |
| Интеграции | API с таймаутами, повтором и журналом ошибок | При росте очереди или критичности обмена |
| Доступ | Проверка прав на сервере для каждого объекта | При добавлении организаций, филиалов и партнёров |
| Наблюдаемость | Логи, ошибки, метрики ответа и резервные копии | При появлении SLA и дежурной команды |
- Назовите три операции, потеря которых останавливает бизнес.
- Зафиксируйте владельца и источник истины для каждого типа данных.
- Опишите поведение системы при недоступности каждого внешнего API.
- Проверьте права не только на экран, но и на конкретную запись.
- Определите, как восстановить систему и сколько данных допустимо потерять.
Архитектура начинается не со стека, а с ограничений
Одно и то же приложение можно собрать разными способами. Правильный выбор зависит от критичных сценариев, количества пользователей, чувствительности данных, интеграций, доступности команды и темпа изменений. До обсуждения фреймворка нужно понять, что система обязана гарантировать.
Функциональные требования описывают действия: создать заказ, согласовать документ, назначить роль, провести платеж. Нефункциональные задают качество: время ответа, доступность, восстановление, аудит действий, срок хранения и географию данных.
Архитектура должна быть соразмерной риску. Для MVP опасна инфраструктура, которую маленькая команда не сможет обслуживать. Для финансово значимого кабинета опасен быстрый прототип без модели прав, журналирования и резервного восстановления.
- Какие три пользовательских сценария критичны для бизнеса.
- Какие данные нельзя потерять или показать не тому пользователю.
- Какие внешние системы и протоколы обязательны.
- Какой рост нагрузки реалистичен в ближайшие 12–18 месяцев.
- Как часто нужно выпускать изменения и кто будет поддерживать продукт.
- Какой простой допустим и сколько времени есть на восстановление.
Базовые слои архитектуры веб-приложения
Интерфейс отвечает за отображение состояния и пользовательские действия. API принимает запрос, проверяет контракт и передает управление бизнес-логике. Доменный слой реализует правила продукта. Доступ к данным сохраняет и извлекает состояние. Инфраструктура связывает очереди, файлы, внешние сервисы и мониторинг.
Разделение не означает отдельный сервер для каждого слоя. На старте они могут находиться в одном приложении и репозитории, но иметь четкие границы в коде. Тогда правила заказа не зависят напрямую от конкретной базы, а интерфейс не содержит расчетов, которые невозможно повторить через API.
Полезная граница проходит там, где меняется причина изменения. Политика скидки меняется из-за бизнеса, компонент кнопки — из-за интерфейса, драйвер платежной системы — из-за внешнего поставщика. Смешивание этих причин делает каждую доработку рискованнее.
| Слой | Ответственность | Чего в нем не должно быть |
|---|---|---|
| UI | Состояние экрана и взаимодействие | Скрытых бизнес-правил и прямого SQL |
| API | Контракт, валидация, авторизация | Случайных форматов и логики интерфейса |
| Домен | Правила и процессы продукта | Зависимости от конкретного UI |
| Данные | Хранение, транзакции, запросы | Решений о пользовательском опыте |
| Инфраструктура | Очереди, файлы, внешние сервисы | Неконтролируемого влияния на домен |
Модульный монолит или микросервисы
Монолит — не синоним хаоса. Модульный монолит хранит продукт в одном развертываемом приложении, но разделяет предметные области: пользователи, заказы, каталог, документы. Он проще в разработке, тестировании и транзакциях, поэтому часто подходит первой версии.
Микросервисы дают независимое развертывание и масштабирование частей системы, но добавляют сетевые отказы, распределенные данные, трассировку, версии контрактов и операционную нагрузку. Они оправданы, когда границы доменов устойчивы, разные части имеют разный профиль нагрузки или ими владеют автономные команды.
Переход можно подготовить без раннего дробления. Сначала выделяют модули и события внутри приложения, запрещают обход границ, документируют контракт. Если конкретный модуль действительно требует независимости, его проще вынести позже.
| Критерий | Модульный монолит | Микросервисы |
|---|---|---|
| Команда | Одна или несколько тесно связанных | Автономные команды с DevOps-компетенцией |
| Данные | Простые общие транзакции | Разделенное владение и eventual consistency |
| Релизы | Общий, но управляемый pipeline | Независимые релизы сервисов |
| Эксплуатация | Ниже порог сложности | Нужны оркестрация, трассировка и SRE-практики |
| Хороший старт | Большинство новых продуктов | Подтвержденные организационные и нагрузочные причины |
Микросервисы решают проблему независимости команд и доменов, а не автоматически делают приложение современным.
Данные, API и интеграции
Модель данных должна выражать бизнес, а не копировать поля экранов. У каждой сущности определяют владельца, жизненный цикл, обязательные инварианты и историю изменений. Например, заказ — не просто форма: у него есть состав, цена на момент покупки, статусы, платежи и последствия отмены.
API проектируют как контракт. Версия, форматы ошибок, идемпотентность, пагинация, авторизация и ограничения описываются до интеграции. Для длительных операций используют очередь и возвращают статус, а не удерживают соединение до завершения.
Вебхуки требуют подписи, повторной доставки и защиты от дублей. Платеж или внешний заказ нельзя создавать повторно только потому, что поставщик повторил уведомление. Подробный чек-лист есть в статье об API-интеграциях.
- Определить источник истиныКакая система владеет клиентом, заказом, оплатой и документом.
- Описать контрактСхема запроса, ответа, ошибки, права и ограничения.
- Учесть повторИдемпотентность команд и дедупликация событий.
- Разделить синхронное и фоновоеБыстрый ответ пользователю, очередь для тяжелой обработки.
- Добавить наблюдаемостьCorrelation ID, журнал интеграций, метрики и оповещения.
Безопасность как архитектурное свойство
Безопасность нельзя добавить в конце одним тестом. Модель ролей влияет на данные и API, управление секретами — на развертывание, аудит — на хранение, обновление зависимостей — на процесс разработки. Эти решения нужно принять до массового написания кода.
Минимальный принцип — наименьшие привилегии. Пользователь, сервис и сотрудник получают только необходимые действия и данные. Проверка выполняется на сервере для каждого защищенного ресурса; скрытая кнопка в интерфейсе не является контролем доступа.
Чувствительные данные классифицируют, шифруют при передаче и хранении там, где это оправдано, ограничивают экспорт и логирование. Резервная копия тоже содержит данные и требует контроля доступа, проверки восстановления и срока хранения.
- Централизованная аутентификация и серверная авторизация.
- Разделение ролей, организаций и областей данных.
- Управление секретами вне репозитория и клиентского кода.
- Валидация входа, защита сессии и лимиты запросов.
- Аудит критичных действий без утечки чувствительных полей.
- Регулярное обновление зависимостей и проверка уязвимостей.
Надежность, развертывание и наблюдаемость
Надежность начинается с определения допустимого отказа. Если отчет можно пересчитать завтра, ему не нужен тот же уровень доступности, что оплате. Для критичных сценариев задают SLO, время восстановления и допустимую потерю данных.
Приложение развертывают воспроизводимо: инфраструктура и конфигурация описаны, миграции обратимы или имеют план отката, среды разделены, секреты управляются отдельно. Контейнеризация помогает повторяемости, но сама по себе не обеспечивает устойчивость.
Наблюдаемость объединяет логи, метрики и трассировку. Команда должна быстро ответить: какой запрос сломался, в каком релизе, для какого клиента, на каком внешнем сервисе и сколько операций затронуто. Среднее время ответа без percentiles и бизнес-контекста скрывает реальные пики.
| Сигнал | На какой вопрос отвечает | Пример |
|---|---|---|
| Метрика | Насколько часто и масштабно | Ошибка оплаты, p95 API, длина очереди |
| Лог | Что произошло в конкретной точке | Статус обработчика без секретов |
| Трассировка | Где задержался сквозной запрос | Gateway → API → база → платежи |
| Бизнес-событие | Как затронут процесс | Заказ не перешел в подтвержденный |
Как принять архитектурное решение и не заморозить продукт
Ключевые решения фиксируют короткими ADR: контекст, варианты, выбранный подход, последствия и условия пересмотра. Это помогает новой команде понять не только что сделано, но и почему. Документ обновляют при изменении исходных ограничений.
Для первой версии выбирают минимальную архитектуру, которая безопасно выполняет критичный сценарий и оставляет путь развития. В статье о разработке ПО разобраны границы заказного решения, а этапы разработки показывают, когда проверять архитектуру.
Архитектурный review проводят до реализации рискованных интеграций и после появления реальных данных о нагрузке. Цель — не защитить первоначальную схему, а регулярно проверять, продолжает ли она помогать продукту.
- Сформулировать сценарии и рискиДанные, нагрузка, доступность, интеграции и команда.
- Выбрать простейший достаточный вариантБез преждевременной распределенности и скрытого долга.
- Зафиксировать границыМодули, владельцы данных, контракты и правила зависимостей.
- Проверить прототипомРискованная интеграция, нагрузка или миграция до полной реализации.
- Пересматривать по фактамМетрики эксплуатации, рост продукта и изменения команды.
FAQ
Частые вопросы
01Какая архитектура лучше для нового веб-приложения?
Для многих новых продуктов разумен модульный монолит: он проще в разработке и эксплуатации, но сохраняет границы доменов. Решение меняется, если есть подтвержденные требования к независимым командам или масштабированию.
02Нужно ли использовать микросервисы для высокой нагрузки?
Не всегда. Сначала измеряют узкое место и масштабируют приложение, кеш, базу или фоновые задачи. Микросервисы оправданы, когда раздельное масштабирование и владение компенсируют операционную сложность.
03Когда выбирать SQL, а когда NoSQL?
Выбор зависит от модели и операций. Транзакционные бизнес-данные часто хорошо подходят реляционной базе; специализированное хранилище добавляют для конкретной задачи, а не вместо моделирования.
04Что должно остаться после архитектурного этапа?
Диаграмма контекста и контейнеров, модель данных, ключевые API-контракты, модель безопасности, решения ADR, план развертывания и прототипы главных рисков.
Источники и документация
Материал подготовлен редакцией ХЭМС на основе проектной практики. Цены и технические условия актуальны на дату публикации и уточняются после разбора задачи.
Обсудить проект
Спроектируем основу web-продукта
Разберем сценарии, данные, интеграции и риски. Зафиксируем границу MVP и архитектуру, которую команда сможет развивать после первого релиза.
