Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Объекты времени компиляции против объектов времени выполненияСодержание книги
Поиск на нашем сайте
Объекты в распределенных системах существуют в различных формах. В наиболее распространенном варианте они соответствуют объектам выбранного языка программирования, например Java, C++ или другого объектно-ориентированного языка, и представляют собой объекты времени компиляции. В этих случаях объект является экземпляром класса. Класс — это описание абстрактного типа в виде модуля, содержащего элементы данных и операций над этими данными [291]. Использование объектов времени компиляции в распределенных системах обычно значительно упрощает создание распределенных приложений. Так, в языке Java объект может быть полностью описан в рамках своего класса и интерфейсов, которые этот класс реализует. Компиляция определения класса порождает код, позволяющий создавать экземпляры объектов языка Java. Интерфейсы можно скомпилировать в клиентские и серверные заглушки, позволяющие обращаться к объектам Java с удаленных машин. Разработчик программы на Java чаще всего может не беспокоиться по поводу распределения объектов: он занимается только текстом программы на языке Java. Очевидная оборотная сторона использования объектов времени компиляции состоит в зависимости от конкретного языка программирования. Существует и альтернативный способ создания распределенных объектов — непосредственно во время выполнения. Такой подход характерен для множества объектных распределенных систем, поскольку распределенные приложения, созданные в соответствии с ним, не зависят от конкретного языка программирования. В част-
114 Глава 2. Связь ности, приложение может быть создано из объектов, написанных на различных языках программирования. При работе с объектами времени исполнения тот способ, которым они будут реализованы, обычно остается открытым. Так, например, разработчик может решить написать на С библиотеку, содержащую набор функций, которые смогут работать с общим файлом данных. Главный вопрос состоит в том, как превратить эту реализацию в объект, методы которого будут доступны с удаленной машины. Традиционный способ состоит в том, чтобы использовать адаптер объектов {object adapter), который послужит оболочкой {wrapper) реализации с единственной задачей — придать реализации видимость объекта. Сам термин «адаптер» взят из шаблона проектирования, описанного в [157], который предоставляет интерфейс, преобразуемый в то, что ожидает клиент. Примером адаптера объектов может быть некая сущность, динамически привязываемая к описанной ранее библиотеке на С и открывающая файл данных, соответствующий текущему состоянию объекта. Адаптеры объектов играют важную роль в объектных распределенных системах. Чтобы сделать оболочку как можно проще, объекты определяются исключительно в понятиях интерфейсов, которые они реализуют. Реализация интерфейса регистрируется в адаптере, который, в свою очередь, создает интерфейс для удаленных обращений. Адаптер будет принимать приходящие обращения и создавать для клиентов образ удаленного объекта. Мы вернемся к вопросам организации серверов и адаптеров объектов в следующей главе. Сохранные и нерезидентные объекты Помимо деления на объекты, зависящие от языка программирования, и объекты времени выполнения существует также деление на сохранные и нерезидентные объекты. Сохранный объект {persistent object) — это объект, который продолжает существовать, даже не находясь постоянно в адресном пространстве серверного процесса. Другими словами, сохранный объект не зависит от своего текущего сервера. На практике это означает, что сервер, обычно управляющий таким объектом, может сохранить состояние объекта во вспомогательном запоминающем устройстве и завершить свою работу. Позже вновь запущенный сервер может считать состояние объекта из запоминающего устройства в свое адресное пространство и обработать запрос на обращение к объекту. В противоположность ему, нерезидентный объект {transient object) — это объект, который существует, только пока сервер управляет им. Когда сервер завершает работу, этот объект прекращает существовать. Использовать сохранные объекты или нет — это спорный вопрос. Некоторые полагают, что нерезидентных объектов вполне достаточно. Сейчас мы не будем вдаваться в детали и вернемся к этому вопросу, когда будем обсуждать объектные распределенные системы в главе 9. Привязка клиента к объекту Интересная разница между традиционными системами RPC и системами, поддерживающими распределенные объекты, состоит в том, что последние обычно
2.3. Обращение к удаленным объектам 115 предоставляют ссылки на объекты, уникальные в пределах системы. Такие ссылки могут свободно передаваться между процессами, запущенными на различных машинах, например как параметры обращения к методу. Путем сокрытия истинной реализации ссылок на объекты (то есть обеспечения их непрозрачности) и может быть даже использования их в качестве единственного средства обращения к объектам прозрачность распределения по сравнению с традиционным механизмом RPC повышается. Когда процесс хранит ссылку на объект, перед обращением к любому из методов объекта процесс должен в первую очередь выполнить привязку к этому объекту. Результатом привязки будет заместитель, размещаемый в адресном пространстве процесса и реализующий интерфейс с методами, к которым обращается процесс. Во многих случаях привязка осуществляется автоматически. Когда базовая система получает ссылку на объект, ей требуется способ отыскать сервер, управляющий этим объектом, и поместить заместителя в адресное пространство клиента. При неявной привязке (implicit binding) клиенту предоставляется простой механизм, позволяющий напрямую запрашивать методы, используя только ссылку на объект. Так, например, в C++ можно переопределить унарный оператор выбора (->) для класса так, чтобы он позволял обращаться со ссылками на объекты как с простыми указателями (листинг 2.1). В случае неявной привязки клиент прозрачно связывается с объектом в момент разрешения ссылки и получения этого объекта в действительности. С другой стороны, в случае явной привязке (explicit binding) клиент должен до обращения к методам вызвать специальную функцию для привязки к объекту. При явной привязке обычно возвращается указатель на локально доступный заместитель, как показано в листинге 2.2.
Листинг 2.1. Пример неявной привязки с использованием только глобальных переменных
116 Глава 2. Связь Реализация ссылок на объекты Очевидно, что ссылки на объекты должны содержать достаточно информации, чтобы обеспечить клиентам привязку к объекту. Простая ссылка на объект должна содержать сетевой адрес машины, на которой размещен реальный объект, вместе с конечной точкой, определяющей сервер, который управляет объектом, и указанием на то, что это за объект. Последний обычно представляется сервером, например, в форме 16-битного числа. Конечная точка в данном случае абсолютно такая же, как и та, что обсуждалась при рассмотрении системы DCE RPC. На практике она соответствует локальному порту, который динамически выделяется локальной операционной системой сервера. Однако эта схема имеет множество недостатков. Во-первых, если в сервере произойдет сбой и после восстановления сервер получит другую конечную точку, все ссылки на объекты станут неправильными. Эту проблему можно решить так же, как это сделано в DCE: создать на машине локального демона, который будет опрашивать известные конечные точки и отслеживать назначения конечных точек серверам в таблице конечных точек. После привязки клиента к объекту мы первым делом запросим у демона текущую конечную точку сервера. Такой подход требует, чтобы мы кодировали идентификатор сервера в ссылке на объект, которая может использоваться в качестве индекса в таблице конечных точек. Сервер, в свою очередь, всегда должен регистрироваться локальным демоном. Однако кодирование сетевого адреса машины сервера в ссылке на объект — вообще говоря, плохая идея. Проблема подобного подхода — в том, что сервер невозможно будет перенести на другую машину, не объявив недействительными все ссылки на объекты, которыми он управлял. Традиционное решение этой проблемы состоит в распространении идеи локальных демонов, поддерживающих таблицы конечных точек, на сервер локализации {location server), следящий за постоянной работой серверов, на которых расположены объекты. Ссылка на объект в результате должна содержать сетевой адрес сервера локализации, а также действующий в системе идентификатор сервера. Как мы увидим в главе 4, это решение также имеет множество недостатков, особенно по части масштабируемости. До настоящего момента мы в тактических целях предполагали, что клиент и сервер уже были каким-то образом сконфигурированы под единый стек протоколов. При этом предполагается, что они используют не только общий транспортный протокол, такой как TCP, но также и общий протокол маршалинга и де-маршалинга параметров сообщения. Они должны также пользоваться общим протоколом для установки исходного соединения, обработки ошибок, контроля потока и пр. Мы можем осторожно отбросить это допущение, если предположим, что к ссылке на объект добавляется дополнительная информация. Такая информация может включать указание на используемый для привязки к объекту протокол, который поддерживается сервером объекта. Так, например, некоторый сервер может одновременно поддерживать прием данных по протоколу TCP и дейта-
2.3. Обращение к удаленным объектам 117 граммы UDP. При этом на клиенте лежит ответственность за реализацию заместителя как минимум для одного протокола, указанного в ссылке на объект. Мы можем пойти еще дальше, включив в ссылку на объект дескриптор реализации {implementation handle), указывающий на полную реализацию заместителя. Эту реализацию клиент может динамически загрузить при привязке к объекту. Например, дескриптор реализации может принимать вид URL-адреса, указывающего на файл архива, типа ftp://ftp.clientware.org/proxies/java/proxy-v1.1a.zip. Протокол привязки в этом случае будет нужен только для указания на то, что данный файл следует динамически загрузить, разархивировать, установить, а впоследствии создать экземпляр. Плюс такого подхода состоит в том, что клиент не должен заботиться о том, доступна ли реализация данного протокола. Кроме того, это дает разработчику объекта полную свободу в разработке специфических для объекта заместителей. Однако, как мы увидим в главе 8, чтобы гарантировать клиенту, что он может доверять загруженному откуда-то коду, нам нужно предпринимать специальные действия по обеспечению защиты.
|
|||||||
Последнее изменение этой страницы: 2016-09-19; просмотров: 296; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.119.112.208 (0.007 с.) |