Рекомендация: Состояние проектирования для приложений J2EE
В этом руководстве обсуждаются механизмы схемы управления состояниями для приложения J2EE.
Взаимосвязи
Основное описание

Введение

Эффективное управление состояниями приложения - это важный аспект проектирования распределенных приложений. В этом руководстве дается обзор некоторых общих замечаний о проектировании и механизмов управления состояниями приложения J2EE.

Замечания о проектировании, связанные с управлением состояниями, относятся к Этапу разработки проекта.   Разработчик программного обеспечения должен изучить общие подходы к управлению состояниями в процессе Анализа & Обучения проектированию Действие: Определить архитектуру кандидата.  При выполнении Задача: Анализ архитектуры, разработчик программного обеспечения должен изучить требования к масштабируемости и производительности приложения, чтобы определить, какие приемы управления состояниями необходимо использовать в приложении для их удовлетворения.   На Этапе разработки проект приложения усовершенствуется, и разработчик должен определить характерные для  J2EE механизмы реализации управления информацией о состоянии приложения в Задача: Идентификация механизмов проекта.

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

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

Технический обзор

Существует нарастающая тенденция к построению распределенных приложений, которые взаимодействуют через Интернет в той или иной форме. Даже хотя  по своей природе Интернет не поддерживает сохранение состояний, существует потребность управлять состояниями для построения любого рода бизнес-приложений. Рассмотрим Интернет-приложение, в котором   пользователь щелкает на ссылке со страницы А на страницу Б. Приложение, которое обрабатывает запрос страницы Б, не имеет доступа к информации, использованной для обработки страницы А.   Такое поведение применимо для статических Web-страниц, но большинство бизнес-приложений требуют информации о предыдущей обработке. В такой ситуации используются механизмы управления состояниями, предоставленные J2EE.

Временное и постоянное состояние

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

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

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

Состояние сеанса

Клиентам Web часто требуется иметь возможность делать множественные запросы браузера при переходе от страницы к странице, сохраняя информацию о клиенте, такую как выбранные товары в корзине. Web-приложения управляют этим, создавая ИД сеанса и связывая с ним данные о состоянии. ИД сеанса и связанные с ним данные называются состоянием сеанса.

Состояние сеанса - это данные, связанные с определенным взаимодействием клиента и web-приложения за короткий период времени (минуты или часы, но не дни). Таким образом, состояние сеанса - это кратковременные данные, которые обычно удаляются после некоторого периода тайм-аута для освобождения ресурсов.

Состояние сеанса можно сохранить на клиенте или на сервере, как описано в следующих разделах. Платформа J2EE предоставляет механизмы, специально предназначенные для управления состояниями сеанса, по причине их важности в web-приложениях.

Основные механизмы хранилища

Ниже приведены основные механизмы, используемые в web-приложениях для сохранения состояний.

Cookies

Cookies - это маленькие текстовые файлы, хранящиеся на web-клиентах. Сервер может сохранять cookie на клиенте. Последующие запросы клиента отправляют cookie на сервер, предоставляя серверу доступ к данным состояния, хранящимся в cookie.

Некоторые проблемы применения cookie:

  • Многие пользователи считают, что cookie ослабляют защиту и/или конфиденциальность, и поэтому они выключают cookie.
  • Существуют ограничения на размер заголовков cookie, и это ограничивает объем данных, который может быть сохранен.
  • Некоторые протоколы, такие как Протокол беспроводного доступа (WAP) не поддерживают cookies.
  • Если клиент входит в систему из другого расположения (например, из другой системы), то сохраненные cookie становятся недоступны.
  • Данные о состоянии должны быть представимы строковыми значениями.

Преобразование URL

Преобразование URL - это механизм для вложения состояния сеанса в URL, указанные на каждой странице. Когда Web-сервер генерирует страницы, которые должны быть доставлены клиенту, он кодирует состояние сеанса в URL страниц. Затем, когда пользователь щелкает на URL, данные о состоянии, сохраненные в URL, отправляются назад на сервер, позволяя ему повторно установить контекст сеанса. Аналогичный механизм использует скрытые поля HTML. Существуют следующие проблемы при использовании этих механизмов:

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

Простой файл

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

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

XML

Поддержка постоянной информации о состоянии в файле XML - это следующий шаг после использования простого файла.   Некоторые преимущества управления состояниями приложения с помощью файла XML по сравнению с использованием простого файла состоят с следующем:

  • Файл XML предоставляет структуру, которая отсутствует в простом файле.
  • Файл XML может быть проанализирован с помощью стандартных API.
  • Файл XML более портативен.

База данных

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

  • Схема таблиц предоставляет структуру.
  • Когда переменная приложения изменена, нет необходимости переписывать всю информацию о состоянии приложения.   Необходимо переписать только измененную информацию.
  • Непротиворечивость может быть обеспечена координацией восстановления состояния приложения с восстановлением рабочей базы данных.
  • Для обеспечения высокой надежности сервер базы данных может быть кластеризован.

Доступ к базам данных может осуществляться с помощью API Java Database Connectivity (JDBC). JDBC можно также использовать для доступа к другим табличным источникам данных, включая электронные таблицы и простые файлы.

Механизмы, характерные для J2EE

Платформа J2EE предоставляет определенные механизмы для управления состояниями. Это механизмы самого высокого уровня, которые могут быть настроены для использования одного или нескольких основных механизмов, описанных ранее.

Контекст сервлета

Сервлеты могут использовать контекст сервлета для сохранения данных, применимых для многих клиентов и клиентских сеансов.

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

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

Объект сеанса HTTP

Сервлеты и JSP могут сохранять данные, связанные с определенным сеансом клиента в Объекте сеанса HTTP. При сохранении данных в объектах сеанса могут возникнуть проблемы при обеспечении доступа к данным сеанса для нескольких серверов. Некоторые производители предоставляют возможность перенаправлять клиентские запросы на один сервер, что называется "родственность серверов".

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

Сервер настраивается для реализации выбранного механизма - JSP и сервлеты независимо кодируются, получая доступ к объекту сеанса с помощью API, указанного в спецификации сервлета.

Объекты EJB

Объекты EJB содержат механизмы высокого уровня для сохранения состояния, основанные на механизмах низкого уровня, описанных ранее, таких как базы данных и файлы. Объекты сеанса с сохранением состояния используются для сохранения данных, связанных с определенным клиентским сеансом, в то время как сущностные объекты JavaBean используются для сохранения данных на долгое время. Более подробная информация о сохранении состояний с помощью объектов EJB находится в разделе Руководство: EJB.

Проектирование состояния сеанса

Клиентам Web часто требуется иметь возможность делать множественные запросы браузера при переходе от страницы к странице, сохраняя информацию о клиенте, такую как выбранные товары в корзине. Web-приложения управляют этим, создавая ИД сеанса и связывая с ним данные о состоянии.

Сам ИД сеанса сохраняется на клиенте с помощью одного или двух механизмов:

  • cookie - браузер клиента посылает этот cookie  на сервер при каждом запросе, позволяя серверу повторно установить состояние сеанса.
  • Преобразование URL - URL на страницах, доставленных клиенту сервером, содержат закодированный ИД сеанса. Когда пользователь щелкает на таком URL, ИД сеанса посылается на сервер, позволяя серверу повторно установить состояние сеанса.

Сервер настраивается для использования выбранного подхода. Сервлеты и JSP должны кодироваться так, чтобы работать независимо от настроенного метода. В частности, для кодирования всех URL используйте метод HttpServletResponse.encodeURL(). Этот метод проверяет, включено ли преобразование URL, и если да, то выполняет кодирование.

Связанные с ИД сеанса данные могут быть сохранены в объекте сеанса HTTP, где к ним могут получить доступ JSP и сервлеты, или в объектах JavaBean сеанса.

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

Выбор подходящего механизма

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

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

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

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

Проектирование длительного сохранения данных о состоянии

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

Подходящий механизм для сохранения таких данных зависит от их вида. Могут применяться cookie, простые файлы, файлы XML и базы данных. Для доступа к базе данных обычно применяется сущностный bean-объект. Более подробная информация находится в разделе Руководство: Сущностный bean-объект.