0 1.3K ru

Паттерны для хранения состояния сеанса из PoEAA

Сохранение состояния сеанса на стороне клиента (Client Session State)

Client Session State паттерн сохраняет состояние сеанса на стороне клиента.

В большинстве случаев для перемещения данных между клиентом и сервером используется объект переноса данных (Data Transfer Object). Он может сериализовать свое содержимое для передачи по сети, тем самым позволяя перемещать весьма сложные структуры данных.

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

С HTML-интерфейсами дело обстоит немного сложнее. Существует три основных способа сохранения состояния сеанса на стороне клиента: параметры адреса URL, скрытые поля (input type="hidden") и файлы cookie.

cleint session state pattern

Назначение

Client Session State обладает массой преимуществ. В частности, он поддерживает использование серверных объектов без состояний, обеспечивая максимальную степень кластеризации и устойчивости к отказам. Разумеется, при отказе системы клиента все данные будут утеряны, однако в подобных ситуациях большинство клиентов ожидают именно такого исхода. Все перечисленные схемы прекрасно подходят для хранения нескольких полей, однако при наличии больших объемов данных вопросы их размещения и временные расходы, вызванные передачей вместе с каждым запросом большого количества информации, становятся весьма критичны. Это особенно верно для HTTP-клиентов.

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

Сохранение состояния сеанса на стороне сервера (Server Session State)

server

Server Session State сохраняет сериализованное представление состояния сеанса на стороне сервера.

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

Подобная базовая схема основана на том предположении, что у сервера приложений достаточно памяти для выполнения таких задач. Кроме того, предполагается, что сервер приложений только один (т.е. кластеризация отсутствует) и что при внезапном отказе сервера приложений сеанс будет утерян, а вся проделанная работа, как говорится, "пойдет коту под хвост".

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

Формат сериализации состояний сеанса должен быть как можно более простым, поскольку основной особенностью сохранения состояния сеанса на стороне сервера является именно простота программирования. Некоторые платформы снабжены простым механизмом, позволяющим сериализовать граф объектов в двоичный формат. Вместо этого объекты сеансов можно сериализовать в какой-нибудь текстовый формат, например в XML.  В этом случае для сохранения состояния сеанса на стороне сервера в таблице базы данных потребуется применить крупный сериализованный объект Serialized LOB. Различные базы данных по-разному обрабатывают крупные объекты, поэтому вопрос производительности во многом зависит от используемой базы данных.

На этом этапе обсуждения мы подошли к определению границы между сохранением состояния сеанса на стороне сервера и сохранением состояния сеанса в базе данных (Database Session State). Эта граница весьма условна. Server Session State переходит в Database Session State, когда данные вместо сериализации преобразуются в стандартный табличный формат.

Так же весьма популярны для хранения состояния сейчас серверы кеширования, такие как Redis или даже Kafka/RabbitMQ.

Назначение

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

Сохранение состояния сеанса в базе данных (Database Session State)

database

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

Одним из наиболее спорных аспектов сохранения состояния сеанса в базе данных является производительность. Использование серверных объектов без состояния разрешает применение пула объектов и облегчает выполнение кластеризации, что, разумеется, оказывает благоприятное влияние на производительность приложения. С другой стороны, необходимость извлечения и записи данных при выполнении каждого запроса влечет за собой определенные временные затраты. Для снижения этих затрат извлекаемые данные можно кэшировать, однако расходы на запись сократить нельзя.

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

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

Источник Martin Fowler

Comments:

Please log in to be able add comments.