Продолжается подписка на наши издания! Вы не забыли подписаться?

Производственные кофейные бобы для чайников

Вводный обзор стандарта серверных компонентов приложений Java

Enterprise JavaBeans (EJB) вызвали всплеск энтузиазма в момент выхода в марте 1998 спецификации Enterprise JavaBeans Specification Version 1.0. Такие фирмы, как Oracle, Borland, Tandem, Symantec, Sybase и Visigenic, в числе множества других объявили и\или выпустили продукты, соответствующие спецификации EJB. Сейчас мы вкратце расскажем, что такое Enterprise JavaBeans. Мы посмотрим, чем отличаются EJB от изначальной компонентной модели JavaBeans и обсудим, почему вокруг них поднялось столько шума.

Но скажем сразу: мы не будем рассматривать исходный код или какие-то прикладные вопросы. Эта статья - не tutorial; а скорее обзор архитектуры. EJB - это большая страна, и, не усвоив основных концепций, бесполезно хвататься за средства разработки и прочие программистские штучки. В будущих выпусках журнала мы расскажем об использовании Enterprise JavaBeans API для создания собственных Enterprise JavaBeans.

Чтобы понять, чем привлекательны EJB для разработчиков, посмотрим назад. Сперва обратимся к истории систем клиент-сервер и к текущему состоянию дел. Затем, рассмотрим разные части EJB-системы: EJB-компоненты -- которые живут в EJB-контейнере , исполняющемся на EJB-сервере -- и EJB-объекты, которые использует клиент как своего рода "дистанционное управление" EJB-компонентами. Мы обратимся к двум типам EJB: session- и entity-объектам. Вы также прочтете о home- и remote-интерфейсах, создающих экземпляры EJB и обеспечивающих доступ к методам EJB, соответственно. В конце концов вы должны получить представление, насколько расширяемы могут быть серверы, использующие Enterprise JavaBeans. Но сперва посмотрим назад.

История технологии клиент-сервер

Древняя история

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

Клиент-сервер спешит на помощь

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

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

Первые системы клиент-сервер были двухуровневыми, где интерфейс пользователя исполнялся на клиенте, а БД жила на сервере. Такие системы и сейчас наиболее распространены. Одно семейство исполняет подавляющую часть бизнес-логики на клиенте, обновляя разделяемые данные с помощью SQL-обращений к серверу. Это гибкое решение, поскольку переговоры клиент-сервер происходят на уровне языка БД. В такой системе правильно спланированный клиент может быть изменен для отражения новых бизнес-правил и условий без модификации сервера при условии, что у сервера есть доступ к элементам схемы БД (таблицам, views и т.д.), необходимым для совершения транзакции. Сервер в такой двухуровневой системе называется сервером БД, как показано на рисунке ниже.

Серверы баз данных, однако, имеют свои недостатки. Часто SQL для конкретной бизнес-функции (например, добавления позиции в заказ) один и тот же от вызова к вызову, за исключением изменяемых или добавляемых данных. Сервер баз данных до бесконечности перемалывает почти идентичные SQL-запросы для каждой бизнес-функции. Например, все SQL-выражения для добавления записи в заказ очень похожи, как и SQL для поиска заказчика в БД. Время, занимаемое такой работой, лучше бы употребить на обработку данных. (От этого есть определенные лекарства, типа планов SQL-выражений и хранимых процедур.) Другая проблема состоит в том, что для изменений версий клиентов и БД все машины должны одновременно остановиться, а не подвергшиеся модификации серверы или клиенты становятся неработоспособными.

Серверы приложений

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

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

И БД, и серверы приложений могут быть усовершенствованы введением в архитектуру дополнительных уровней. Так называемая трехуровневая архитектура предполагает наличие промежуточного компонента между клиентом и сервером. Это звено -- middleware -- возникло для лечения болезней двухуровневых систем. Монитор транзакций, один из типов middleware, получает потоки запросов от множества клиентов, и может управлять загрузкой нескольких серверов. Он обеспечивает защиту от сбоя в случае падения сервера и управляет транзакциями в интересах клиента. Другие типы middleware обеспечивают трансляцию коммуникационных протоколов, объединение запросов и откликов клиентов и множественных гетерогенных серверов (это особенно популярно в business process reengineering при работе с унаследованными системами), и/или обеспечивают функции контроля и регуляции сетевого траффика.

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

Объектно-ориентированные языки и технологии нынче в моде, и системы клиент-сервер весьма заметно сдвинулись в сторону объектной ориентации. CORBA (Common Object Request Broker Architecture) - это архитектура, разрешающая объектам, живущим внутри приложений. -- даже объектам, написанные на различных языках -- работать на разных машинах, в зависимости от потребностей данного приложения. Приложения, написанные давным-давно, могут быть упакованы как CORBA-сервисы и взаимодействовать с новой системой. Enterprise JavaBeans, разработанные как CORBA-совместимые, представляют еще один подхход к объектно-ориентированному взаимодействию клиента и сервера.

Enterprise JavaBeans и расширяемые серверы приложений

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

Главная идея Enterprise JavaBeans - обеспечить базу для компонентов, которые могут быть "подключены" к серверу, расширяя его функциональность. Enterprise JavaBeans похожи на исходные JavaBeans только использованием некоторых сходных концепций. Технология EJB управляется не спецификацией компонентов JavaBeans, но совершенно другой (и здоровенной) спецификацией Enterprise JavaBeans (EJB Spec). Спецификация EJB вызывает разных игроков клиент-серверной системы EJB, описывает, как EJB взаимодействуют с клиентом и с существующими системами, по буквам разбирает совместимость EJB и CORBA и определяет границы ответственности различных компонентов системы.

Цель Enterprise JavaBeans

EJB Spec пытается разом убить нескольких зайцев:  

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

EJB Spec определяет основную структуру среды EJB, и, далее, особо определяет отношения между ними. Границы ответственности клиента, сервера, индивидуального компонента четко оговорены. (Мы вернемся к этим структурам чуть ниже.) Разработчик компонента Enterprise JavaBean - это совсем другая роль, нежели разработчик EJB-совместимого сервера, и спецификация описывает, за что отвечает каждый из них.  

Цель EJB - стать стандартным путем построения клиент\сервер-приложений на языке Java. Как и исходные JavaBeans (или компоненты Delphi, или любые другие) от разных поставщиков могут быть скомбинированы для получения клиентских приложений, серверные EJB-компоненты различных разработчиков могут быть использованы для создания серверных приложений. EJB-компоненты, являясь Java-классами, будут исполняться на любом EJB-совместимом сервере без перекомпиляции. Это преимущество, которого не могут предложить платформно-зависимые решения.  

Наконец, EJB совместимы и с другими Java API, могут взаимодействовать с приложениями на других языках, и совместимы с CORBA.

Как работает клиент-серверная система EJB

Чтобы понять, как работает клиент-серверная система EJB, нужно разобраться в работе основных частей EJB-системы - EJB-компонента, EJB-контейнера и EJB-объекта.

Компонент Enterprise JavaBeans

Enterprise JavaBean - это компонент, точно как обычный JavaBean. Enterprise JavaBeans исполняется внутри EJB-контейнера, который, в свою очередь, исполняется на EJB-сервере. Любой сервер, который может содержать EJB-контейнер и предоставлять ему необходимые сервисы, может работать EJB-сервером. (Это значит, что многие из существующих серверов могут быть модернизированы до EJB-серверов, и, в действительности, многие поставщики уже сделали или объявили о намерениях сделать это.)

EJB-компонент - это тип EJB-класса, который, собственно и следует расценивать как "Enterprise JavaBean." Это Java-класс, написанный разработчиком EJB, который воплощает бизнес-логику. Все другие классы в EJB-системе либо обеспечивают клиентский доступ, либо предоставляют сервисы классам компонентов EJB.

Контейнер Enterprise JavaBeans

EJB-контейнер - это место, где "живут" EJB-компоненты. EJB-контейнер предоставляет службы вроде управления транзакциями, ресурсами и версиями, масштабируемости, мобильности и всякой прочей безопасности содержащимся в нем EJB-компонентам. Так как EJB-контейнер берет на себя все эти функции, разработчик EJB-компонентов может сосредоточиться на бизнес-правилах и оставить управление БД и прочие мелочи контейнеру. Например, если какой-то EJB-компонент решит, что текущую транзакцию стоит откатить, он просто скажет об этом контейнеру (в стиле, определенном EJB Spec), а уж контейнер отвечает за все откаты или другие действия, необходимые для остановки производимой транзакции. Внутри одного EJB-контейнера обычно сосуществуют несколько EJB-компонентов.

EJB-объект и удаленный интерфейс

Клиентские программы вызывают методы удаленных EJB. EJB-объект реализует "удаленный интерфейс " EJB-компонента на сервере. Удаленный интерфейс представляет методы EJB-компонента. Именно через него производится полезная работа EJB-объекта, такая, как создание формы заказа или направление пациента к специалисту. Ниже мы обсудим удаленный интерфейс более подробно.

EJB-объекты и EJB-компоненты - это отдельные классы, хотя "снаружи" (то есть, глядя на интерфейсы), они выглядят одинаковыми. Это потому, что они оба реализуют один и тот же интерфейс (удаленный интерфейс EJB-компонента), но делают совсем разные вещи. EJB-компонент исполняется на сервере в EJB-контейнере и реализует бизнес-логику. EJB-объект исполняется на клиенте и удаленно выполняет методы EJB-компонента.

На минуту представьте, что ваш видеомагнитофон - это EJB-компонент. EJB-объект в данном случае аналогичен пульту дистанционного управления: и видеомагнитофон, и пульт имеют одинаковые кнопки, но выполняют разные функции. Нажатие кнопки "Назад" на пульте дистанционного управления видеомагнитофоном эквивалентно нажатию кнопки на самом видеомагнитофоне, несмотря на то, что пленку реально перематывает магнитофон, а вовсе не пульт.

Аналогично, вызовите метод addEmployee()на EJB-объекте, и он вызовет (непрямо, через сеть) метод addEmployee()на удаленном EJB-компоненте. (На самом деле вызов проходит через EJB-контейнер, но это уже детали.) В дополнение, у Enterprise JavaBeans есть home-интерфейс (обсуждаемый ниже), который (чтобы расширить аналогию) поможет вам найти ваш "пульт ДУ", даже если он завалился между диванными подушками.

Откуда взялся класс EJB-объекта и как он работает?

Реальное воплощение EJB-объекта создается кодогенератором, поставляемым с EJB-контейнером. Интерфейсы EJB-объекта - это удаленные интерфейсы EJB-компонента. EJB-объект (созданный контейнером и связанными с ним средствами) и EJB-компонент (созданный разработчиком EJB) реализуют одни и те же удаленные интерфейсы. Для клиента EJB-объект выглядит как объект из домена приложения-- например, бланк заказа. Но EJB-объект - это только замена реального EJB, работающего на сервере в EJB-контейнере. Когда клиент вызывает метод EJB-объекта, этот метод связывается с удаленным EJB-контейнером, требуя вызова того же метода с теми же аргументами на соответствующем удаленном EJB. См. Рис. 1. Это главная концепция работы системы EJB-клиент/сервер.

Enterprise JavaBeans на клиентской и серверной сторонах

Типы Enterprise JavaBeans

Есть два основных типа Enterprise JavaBeans: session beans и entity beans. Эти два типа играют разные роли в распределенном EJB-приложении.

Сессионный, или Session bean - это экземпляр EJB, ассоциированный с конкретным подключением отдельного пользователя клиентом. Session beans обычно не перманентны (хотя и могут быть таковыми), и могут участвовать, а могут и не участвовать в транзакциях. В частности, session-объекты обычно не переживают сбоев сервера. Примером session-объекта может быть EJB, который живет на Web-сервере, предоставляющем пользователю HTML-страницы, и отслеживает перемещения пользователя по сайту. Когда пользователь покидает сайт, или по истечению указанного времени ожидания, session-объект будет уничтожен. Заметьте, что хотя этот session-объект и может сохранять информацию в БД, его назначение не в создании или обновлении содержания БД, он соответствует одному клиенту, производящему некие действия с серверными EJB.

Сущностные, или entity bean предоставляют пользователю информацию, обычно хранящуюся в БД. Entity beans ассоциированы с транзакциями БД, и могут предоставлять доступ к данным множеству пользователей. Поскольку данные, представляемые ими, существуют постоянно, entity beans переживают сбои сервера (после перезагрузки сервер воссоздаст bean по имеющимся данным.) В реляционных терминах, entity bean должен представлять строку нижележащей БД или единичную строку результата SELECT. В объектно-ориентированной БД (OODB) entity bean может представлять единичный объект с его ассоциированными атрибутами и связями. Примером entity bean может служить объект Employee для конкретного работника в БД персонала компании.

Клиент Enterprise JavaBeans создает EJB-объекты на сервере (чуть позже мы выясним, как именно) и манипулирует ими как локальными объектами. Это делает разработку EJB-клиентов почти столь же простым делом, как и разработка локального клиента: разработчик просто создает, использует и уничтожает объекты, но эти объекты имеют соответствующие им эквиваленты, работающие на сервере и выполняющие реальные действия. Session beans управляют информацией, относящейся к взаимодействию клиента и сервера, а entity beans представляют и манипулируют данными приложения. Попытайтесь осмыслить это, как замену на entity beans различных запросов, используемых в двух- или трехуровневых системах, в то время, как session beans делают все остальное.

Каждый EJB имеет уникальный идентификатор. В случае entity beans этот уникальный идентификатор гарантирует идентичность информации. Например, EmployeeIDNumber может уникально идентифицировать объект Employee. Это аналог концепции первичного ключа в реляционных системах БД. Уникальный идентификатор session bean хоть как-то отличает его от других аналогичных beans: это может быть имя хоста и номер порта удаленного соединения, или даже случайно сгенерированный ключ, используемый клиентом для уникальной идентификации данного боба.

Создание серверных beans: home-интерфейс

Итак, клиентская программа связывается с сервером и требует создать Enterprise JavaBean для нужной обработки данных. Сервер отвечает созданием серверного объекта (экземпляра EJB-компонента), и возвратом proxy-объекта (EJB-объект), чьи интерфейсы те же, что и у EJB-компонента и чья реализация производит удаленный вызов (remote method invocations - RMI) в интересах клиента. Клиент использует EJB-объект как локальный объект, "не имея понятия", что на самом деле всю работу выполняет удаленный объект.

Как же клиентская программа создает объекты на сервере? За операции, относящиеся к жизненному циклу серверных beans, отвечает EJB-контейнер. Клиентская программа связывается с контейнером и требует создать объект конкретного типа, а контейнер соответственно создает EJB-объект, который можно использовать для управления новым EJB-компонентом.

Каждый класс EJB-компонентов имеет так называемый home-интерфейс, определяющий методы создания, инициализации, уничтожения и (в случае entity beans) поиска экземпляров на сервере. Home interface - это контракт между классом EJB-компонентов и их контейнером, который описывает создание, уничтожение и поиск экземпляров EJB.

Home-интерфейс EJB расширяет интерфейс javax.ejb.EJBHome, описывающий базовую функциональность home-интерфейса. Все методы этого интерфейса должны быть Java RMI-совместимыми. (Рассуждения о том, что означает "RMI-compatible" выходят за рамки этой статьи.) EJB home-интерфейс также описывает один или более методов create(), с единственным именем create, но различными описаниями. Возвращаемые значения этих методов создания объектов являются удаленным интерфейсом EJB. Как сказано выше, удаленный интерфейс состоит из бизнес-методов, предоставляемых EJB. (Мы вкратце коснемся удаленного интерфейса.)

Когда клиент хочет создать серверный bean, он использует Java Naming and Directory Interface (JNDI) для нахождения home-интерфейса нужного класса bean. JNDI - стандартное расширение ядра Java которое обеспечивает глобальный сервис для любой Java-среды, позволяя Java-программам отыскивать и использовать ресурсы по имени, получать информацию об этих ресурсах, и отслеживать их структуру. Использование JNDI - пример совместимости EJB с другими Java API. Оставим в стороне необходимость знаний и навыков работы с JNDI для поиска home-интерфейса, эта статья - не более, чем обзор.

Имея home-интерфейс EJB-класса, который надо создать, клиент вызывает один из методов create() для создания серверного объекта. Клиентский объект home-интерфейса производит вызов удаленного метода EJB-контейнера на сервере, который затем создает EJB-компонент и возвращает EJB-объект клиенту. Клиент может затем вызывать методы EJB-объекта, которые перенаправляются контейнеру. Контейнер, как правило, перекладывает реализацию метода на EJB-компонент, хотя и сам он отвечает за отслеживание некоторых условий (например, отсутствие нужного EJB-компонента) и возбуждение исключений.

Entity beans имеют также дополнительный метод home-интерфейса finder, находящий индивидуальные персистентные JavaBeans по их первичным ключам. home-интерфейс можно использовать, например, для создания экземпляра объекта ProductionFacility, а затем методу finder можно передать номер ProductionFacilityCode для поиска объекта, представляющего конкретное устройство.

Home-интерфейс также включает метод, говорящий контейнеру удалить экземпляр EJB-компонента на стороне сервера. Этот метод уничтожает экземпляр на стороне сервера. Попытка использования EJB-объекта, соответствующего несуществующему (уничтоженному) EJB, вызывает исключение.

Использование серверных beans: удаленный интерфейс

Если у клиента есть EJB-объект, он может вызывать методы этого объекта, являющиеся реализацией удаленного интерфейса класса EJB-компонента. Удаленный интерфейс EJB расширяет интерфейс javax.ejb.EJBObject, и может определять любые желаемые методы. Небольшим ограничением является то, что типы аргументов и возвращаемые значения метода должны быть совместимы с RMI, и что каждый метод должен содержать java.rmi.RemoteException в операторе throws. Далее, каждый метод в удаленном интерфейсе EJB должен точно соотноситься с соответствующим методом в классе компонента EJB, представленном интерфейсом.

Выводы

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

Ответ Enterprise JavaBeans - создать клиента с помощью удаленных интерфейсов. Эти удаленные интерфейсы реализованы на клиенте как удаленные вызовы того или иного сорта, и они же реализуются на сервере как доменная функциональность. EJB-сервер используетuses JNDI для публикации доступности этих сервисов. Клиент использует JNDI для нахождения home-интерфейса нового класса по имени, и затем использует его для создания объектов с удаленным интерфейсом, который и предоставляет сервис. Это-то позднее связывание доступных интерфейсов на сервере и имен интерфейсов и делает EJB-server расширяемым в процессе работы.

Это введение в Enterprise JavaBeans только скользит по поверхности этой технологии. Мы даже не затронули темы масштабируемости, распределенной обработки, развертывания, безопасности или транзакций. Оставим эти темы на потом. С базовым пониманием среды Enterprise JavaBeans вы готовы к главному -  начать!


Copyright © 1994-2016 ООО "К-Пресс"