img

Stateful и Stateless- архитектуры – объяснение для новичков

 

В программировании понятие «состояние» (state) относится к состоянию системы, компонента или приложения в какой-то определенный момент времени. 

Приведем простой пример. Допустим, вы совершаете покупки на amazon.com, и будь то факт того, что вы вошли в данный момент на сайт, или есть ли какие-то товары в вашей корзине, это все является примерами состояния. 

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

Понятие «состояние» относится к многим компонентам архитектуры. Шаблоны проектирования (например, REST или GraphQL), протоколы (например, HTTP и TCP), межсетевые экраны и функции могут как сохранять состояние, так и не делать этого. Однако основной принцип «состояния» (независимо от компонента, к которому оно привязывается) остается прежним.

В этой статье мы расскажем, что такое состояние. Кроме того, мы объясним, что такое stateful и stateless-архитектуры, а также их плюсы и минусы.

Что такое stateful-архитектура?

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

Иллюстрация: официант принимает заказ в пиццерии

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

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

Иллюстрация: другой официант не может изменить заказ клиента

У этого официанта нет информации о вашем заказе, то есть о вашем состоянии. И по понятным причинам он не сможет проверить статус вашего заказа или внести в него изменения. Ресторан, где сообщать о готовности заказа или вносить в него изменения могут только официанты, принявшие этот заказ, придерживается архитектуры с сохранением состояния (stateful). 

Подобным образом stateful-приложение будет иметь сервер, который будет запоминать данные клиентов (то есть их состояния). Все будущие запросы будут перенаправляться через балансировщик нагрузки (придерживаясь при этом механизма «липких сессий» (Sticky Sessions)) на тот же сервер. Таким образом, сервер всегда будет знать все о клиенте. 

На схеме ниже показаны два разных пользователя, и они оба хотят получить доступ к веб-серверу через балансировщик нагрузки. Так как состояние приложения сохраняется на сервере, пользователи при каждом запросе должны направляться на один и тот же сервер, чтобы сохранять состояние.

Схема: как работает stateful-приложение

Sticky sessions (липкие сессии) – это настройка, позволяющая балансировщику нагрузки раз за разом направлять запросы пользователя на один и тот же внутренний сервер на протяжении всей сессии. В этом и заключается ее отличие от обычной балансировки нагрузки, при которой запросы пользователя направляются на любой доступный сервер по циклическому алгоритму или по какому-то другому шаблону распределения нагрузки.

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

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

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

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

Кроме того, добиться масштабируемости в час пик, например, в Черную пятницу, при использовании stateful-структуры будет не так просто. Структура будет автоматически масштабироваться, добавляя новые серверы, но, так как работает механизм «липких сессий», клиенты будут направляться на одни и те же серверы, что может привести к их перегрузке, что, в свою очередь, приведет к увеличению времени отклика, и это плохо скажется на взаимодействии с пользователем.

Многие из этих проблем может решить stateless-архитектура.

Что такое stateless-архитектура?

Stateless-архитектура – это термин, который в какой-то степени сбивает с толку, так как подразумевает, что система не фиксирует состояние. Но тем не менее такой тип архитектуры вовсе не означает, что информация о состоянии нигде не сохраняется. Это лишь значит, что информация о состоянии хранится вне сервера. Так что, понятие «stateless» может применяться только к серверу. 

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

Иллюстрация: «забывчивый» официант принимает заказ, а затем обращается к компьютеру, чтобы получить больше информации о заказе

Сохраняя «состояние» заказа клиента в централизованной системе, которая доступна всем официантам, любой из них может обслужить любого клиента. 

В рамках stateless-архитектуры HTTP-запросы от клиентов могут отправляться на любой из серверов. 

Как правило, состояние хранится в отдельной базе данных, которая доступна для всех серверов. Таким образом, вы получаете отказоустойчивую и масштабируемую архитектуру, так как при необходимости вы можете удалять или добавлять серверы, не влияя при этом на данные о состоянии.

Кроме того, нагрузка будет равномерно распределяться по всем серверам, так как балансировщику нагрузки не нужно придерживаться схемы липких сессий для направления одних и тех же клиентов на одни и те же сервера. 

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

Иллюстрация: схема stateless-архитектуры

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

Объединяем все вместе

В этой статье описывается, как работают веб-приложения с сохранением и без сохранения состояния, а также их недостатки. Однако принципы stateful и stateless-архитектуры могут применяться не только к веб-приложениям.

Если мы в качестве примера посмотрим на сетевые протоколы, то увидим, что, например, HTTP – это протокол без сохранения состояния. Это значит, что каждый HTTP-запрос от клиента к серверу является независимым и не содержит информации о предыдущих запросах или их содержимом. Сервер обрабатывает каждый запрос как отдельную транзакцию и по определению не сохраняет информацию о состоянии клиента между запросами. 

Состояние может храниться либо на серверах (stateful-архитектура), либо в отдельной базе данных вне серверов (stateless-архитектура). Сам по себе HTTP-протокол не сохраняет состояние. 

В отличие от HTTP, который не сохраняет состояние, TCP-протокол устанавливает соединение и сохраняет состояние. Он устанавливает соединение между двумя устройствами (как правило, это клиент и сервер) и поддерживает непрерывный канал связи до тех пор, пока соединение не будет завершено.

Та же логика может применяться и к межсетевым экранам – они могут как сохранять состояние, так и не делать этого. 

В AWS группа безопасности – это виртуальный брандмауэр, который контролирует входящий и исходящий трафик виртуальных машин или облачных экземпляров. Группы безопасности сохраняют состояние. Когда вы пропускаете определенный входящий трафик, соответствующий исходящий трафик пропускается автоматически. Иными словами, отслеживается состояние соединения.

Для управления входящим и исходящим трафиком в AWS на уровне подсети используются Списки управления сетевым доступом (NACL - Network Access Control Lists), которые не сохраняют состояние. Отсутствие фиксации состояния говорит о том, что вы должны явно определить правила как для входящего, так и для исходящего трафика.

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

Функции и шаблоны проектирования тоже могут сохранять или не сохранять состояние.

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

Надеюсь, что теперь вы стали лучше понимать, как работают stateful и stateless-приложения, и сможете решить, какой вариант вам больше подходит. 

Ссылка
скопирована
Получите бесплатные уроки на наших курсах
Все курсы
Программирование
Скидка 25%
Python-программист с нуля
Стань разработчиком на одном из самых популярных языков программирования.
Получи бесплатный
вводный урок!
Пожалуйста, укажите корректный e-mail
отправили вводный урок на твой e-mail!
Получи все материалы в telegram и ускорь обучение!
img
Еще по теме:
img
В этой статье обсудим один из важнейших аргументов функции, который ТЫ, мой друг, будешь использовать в каждом своем боте.  Ты с
img
Введение    Настало время глубже погрузиться во взаимодействие человека с ботом. Сегодня изучим декоратор message_handler(). Узн
img
Погружение в aiogram (#5 Отправка стикеров)   Введение   Продолжаем изучать функционал библиотеки aiogram для работы с Telegram
img
Гипервизор - это программное обеспечение для виртуализации, используемое для создания и запуска виртуальных машин (ВМ). Гипервиз
img
Виртуализация серверов позволяет запускать несколько виртуальных машин на одном физическом сервере. Запуск виртуальных машин (ВМ
img
Сегодня мы рассмотрим, как настроить и использовать PHP в проекте. Но прежде чем начать, нужно понять, что такое PHP. Что такое
ЗИМНИЕ СКИДКИ
40%
50%
60%
До конца акции: 30 дней 24 : 59 : 59