Stateless vs Statefull

Вопрос:

Stateless - состояние не хранится на сервере. Т.е. в каждом новом запросе мы передаём свой логин/пароль (если в приложении есть авторизация), а также данные для запроса.

Statefull - на сервере открывается сессия. Благодаря этому нам не надо постоянно отправлять на сервер логин/пароль. И не надо отсылать какие-то дополнительные данные (например выбранную локализацию), они хранятся в сессии.

И ещё я выделил три уровня того, где могут храниться временные данные (например, корзина товаров):

Куки
Сессия
База данных
И я запутался. Например, в основном рекомендуется делать приложения Stateless. Но как в этой концепции обработать ту же корзину товаров? Потому что хранить её в куках не очень разумно, а если её не хранить в сессии (потому что сессии в stateless исключаются), то что остаётся - хранение в БД?

Я понимаю, что для REST stateless подходит идеально, потому что там единичные запросы и проще не создавать сессию, чем создавать. Ну а как быть с приложениями с UI? Где мне хранить корзину товаров? Может быть понятия stateless и statefull в принципе применимы только к REST API?

Таким образом вопрос у меня в том, что такое stateless и statefull, очень желательно с примерами, что будет считаться stateless, а что нет.

Software Composition Analysis (анализ состава программного обеспечения).

Ответ:

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

Могу немного расшифровать, почему стейтлесс является модным.

Дело - в горизонтальном масштабировании.

Когад у вас миллион клиентов, и все они бесперывно что то покупают - то один веб - сервер не справляется. Ставят целуб “батарею” веб серверов, а перед ними - так называемый “распределитель нагрузки”, который будет “кидать” пользовательский коннект на тот или иной сервер. Или раунд-робином (грубо говоря, по очереди), или на наименее загруженный в данный момент сервер.

Но вот беда. При этом один и тот же пользователь при кадом запросе “чего нибудь” с сервера может попадать на разные сервера. И ему пришлось бы или как “таскать за собой” сессию или… или хранить всё у себя, и каждый раз передавать на сервер.

Вторая причина стетлесса - простота тестирования. Понимаете, состояние - это такая штука, которую сложно воспроизвести во время автоматизированных тестов. А если всё “состояние” - это заранее оперделенная структура (например, json с определенными полями, о значении котрых ВСЕ известно) - то задача становится гораздо проще.

Теперь - у вас есть аргументы в пользу стетлесса.

И нам осталось одно: помирить эти два прекрасных мира.

Сделать это нетрудно.

Во первых, во многих серверных фремворках (и я говорю “фремворки”, включая сюда как чистый PHP, так и что то понавороченее), есть возможность storage session to redis - ну, короче, в базе данных, только в очень простой, очень быстрой и, скорее всего, лежащей прямо в памяти.

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

Ну и наконец, хранить “корзину” на клиенте при современном развитии JS и вообще всего-всего - это фигня-вопрос. Фактически, Вам достаточно посылать тот же самый json-чик каждый раз, когда Вы что то делаете на сайте. И в это json-чике описано все-все-все. Добавили товар - изменился json. Удалили - опять изменился. Попросили скидку - этот факт отражен в Json’е. То есть, есть взаимно - однозанчное соответствие “что вижу на экране - то описано в состоянии”.

Ну, а отсюда Вам прямая дорога в реакт. Реакт - это штука, которая предназначена для работы с состоянием.

На этом я заканчиваю свой краткий ответ, и надеюсь, что чем то смог Вам помочь

Спасибо. Я правда на джаве работаю, но в принципе там то же самое. У меня вот есть пара вопросов: 1. БД при горизонтальном масштабировании получается остаётся всё так же одна? Или её тоже можно масштабировать? 2. Про корзину не вполне понял, что вы имеете в виду. Ну то есть понял, но такая корзина сразу сотрётся, как только клиент покинет мой сайт? Ведь при возвращении json-у будет неоткуда браться. 3. По поводу redis - интересно, я не первый раз встречаю рекомендацию хранить сессии в нём)) Redis лучше всего подходит для этого, правильно я понимаю? Или это просто совпадение? –
Zhenyria
Commented12 февр. 2021 в 7:25
По поводу корзины я так понял. То есть мы добавили товар в корзину. Потом при загрузке новой страницу в запрос подставляется json с нашей корзиной, ну и получается stateless. –
Zhenyria
Commented12 февр. 2021 в 7:28
3
Приветствую. База данных в случае горизонтального масштабирования - как правило, одна. Но за счет всяких кеширований и т.п. - можно снизить на неё нагрузку. Но у баз данных есть такаие штуки, как партиционирование и шардирование - можно считать, что они тоже подвержены горизонтальному масштабированию. 2) Да, Вы правы. Обычно бы так и было бы. Но следующим “наворотом” будет то, что json’чик будет еще и каждый раз сохранться в local storage браузера. 3) Думаю, Вам лучше подскажет гугл: редис это стандартное решение, но всовременном мире для каждой проблемы есть больше одного инструмента :-) –
S.H.
Commented12 февр. 2021 в 8:19

Поделиться