При такой архитектуре пользователи отправляют запросы к приложению через мобильное приложение или веб-браузер. Магия интернет-сети (см. главу 3) доставляет эти запросы к сервису приложения, который работает на машине, размещённой в корпоративном или коммерческом облачном центре обработки данных. Для связи используется стандартный сетевой протокол прикладного уровня, как правило, HTTP.
Служба приложений выполняет код, поддерживающий API, который клиенты используют для отправки HTTP-запросов. Получив запрос, служба выполняет код, связанный с запрошенным API. При этом в зависимости от семантики API он может производить чтение из базы данных или запись в другую внешнюю систему. По завершении запроса сервис отправляет результаты клиенту для отображения в его приложении или браузере.
Многие, если не большинство, из систем концептуально выглядят именно так. Код прикладного сервиса использует среду исполнения сервера, позволяющую одновременно обрабатывать несколько запросов от нескольких пользователей. Существует огромное количество таких технологий сервера приложений — например, Java EE и Spring Framework для Java, Flask для Python — которые широко используются в данном сценарии.
Такой подход приводит к так называемой монолитной архитектуре. Монолитные архитектуры, как правило, усложняются по мере расширения функциональности приложения. Все обработчики API встроены в код одного сервера. Это в конечном итоге затрудняет быструю модификацию и тестирование, а исполняемое приложение может стать очень тяжеловесным, поскольку все реализации API выполняются в одном и том же прикладном сервисе.
Тем не менее, если нагрузка на запросы остаётся относительно невысокой, то такая архитектура приложения может быть вполне достаточной. Сервис имеет возможность обрабатывать запросы со стабильно низкой задержкой. Но если нагрузка на сервис растёт, то это означает, что задержки будут увеличиваться, так как мощности процессора/памяти сервиса не хватает для одновременного объёма запросов, и, следовательно, запросы будут обрабатываться дольше. В этих условиях наш единственный сервер перегружен и становится узким местом.
В этом случае первой стратегией масштабирования обычно является «наращивание» аппаратного обеспечения службы приложений. Например, если приложение работает на AWS, можно модернизировать сервер со скромного экземпляра t3.xlarge с четырьмя (виртуальными) процессорами и 16 Гбайт памяти до экземпляра t3.2xlarge, что удвоит количество процессоров и памяти, доступных для приложения.
Вертикальное масштабирование (scaling up) — это просто. С его помощью многие реальные приложения проходят долгий путь к поддержке больших рабочих нагрузок. Очевидно, что это требует больших затрат на аппаратное обеспечение, но для вас это масштабирование.
Однако неизбежно, что для многих приложений нагрузка вырастет до уровня, который приведет к загрузке одного серверного узла, независимо от количества процессоров и объёма памяти. Тогда возникает необходимость в новой стратегии — горизонтальном масштабировании (scaling out), о котором я говорил в главе 1.