Э. Таненбаум, М. ван Стеен - Распределённые системы (принципы и парадигмы) (1162619), страница 28
Текст из файла (страница 28)
Доступ к методам можно получить через интерфейс. Важнопонять, что единственно правильным способом доступа или манипулированиясостоянием объекта является использование методов, доступ к которым осуществляется через интерфейс этого объекта. Объект может реализовывать множествоинтерфейсов. Точно так же для данного описания интерфейса может существовать несколько объектов, предоставляющих его реализацию.Это подразделение на интерфейсы и объекты, реализующие их, очень важнодля распределенных систем.
Четкое разделение позволяет нам помещать интерфейс на одну машину при том, что сам объект находится на другой. Структура,показанная на рис. 2.16, обычно и m^hiBdieTC^ распределенным объектом {distributed object).Машина сервераМашина клиента^ Объект• СостояниеТот же интерфейс,что и у объектаКлиентобращается .к методуОперационнаясистемаклиентаСетьСкелетонвызываетдля объектатот же метод• МетодИнтерфейсОперационнаясистемасервераТПараметры вызова послемаршалинга передаются по сетиРис. 2 . 1 6 . Обобщенная организация удаленных объектовс использованием заместителя клиента2.3.
Обращение к удаленным объектам113Когда клиент выполняет привязку к распределенному объекту, в адресноепространство клиента загружается реализация интерфейса объекта, называемаязаместителем {рюху). Заместитель клиента аналогичен клиентской заглушкев системах RPC. Единственное, что он делает, — выполняет маршалинг параметров в сообщениях при обращении к методам и демаршалинг данных из ответныхсообщений, содержащих результаты обращения к методам, передавая их клиенту.
Сами объекты находятся на сервере и предоставляют необходимые клиентской машине интерфейсы. Входящий запрос на обращение к методу сначала попадает на серверную заглушку, часто именуемую скелетоном {skeleton). Скелетонпреобразует его в правильное обращение к методу через интерфейс объекта, находящегося на сервере. Серверная заглушка также отвечает за маршалинг параметров в ответных сообщениях и их пересылку заместителю клиента.Характерной, но немного противоречащей интуитивному представлению особенностью большинства распределенных объектов является то, что их состояние(данные) не распределяется — оно локализовано на одной машине.
С других машин доступны только интерфейсы, реализованные в объекте. Такие объекты ещеназывают удаленными {remote object). Как мы увидим в последующих главах приобщем знакомстве с распределенными объектами, их состояние может быть физически распределено по нескольким машинам, но это распределение также скрывается от клиентов за интерфейсами объектов.Объекты времени компиляции противобъектов времени выполненияОбъекты в распределенных системах существуют в различных формах. В наиболее распространенном варианте они соответствуют объектам выбранного языкапрограммирования, например Java, C++ или другого объектно-ориентированногоязыка, и представляют собой объекты времени компиляции.
В этих случаях объект является экземпляром класса. Класс — это описание абстрактного типа в видемодуля, содержащего элементы данных и операций над этими данными [291].Использование объектов времени компиляции в распределенных системахобычно значительно упрощает создание распределенных приложений. Так, в языке Java объект может быть полностью описан в рамках своего класса и интерфейсов, которые этот класс реализует. Компиляция определения класса порождает код, позволяющий создавать экземпляры объектов языка Java.
Интерфейсыможно скомпилировать в клиентские и серверные заглушки, позволяющие обращаться к объектам Java с удаленных машин. Разработчик программы на Java чаще всего может не беспокоиться по поводу распределения объектов: он занимается только текстом программы на языке Java.Очевидная оборотная сторона использования объектов времени компиляциисостоит в зависимости от конкретного языка программирования.
Существуети альтернативный способ создания распределенных объектов — непосредственново время выполнения. Такой подход характерен для множества объектных распределенных систем, поскольку распределенные приложения, созданные в соответствии с ним, не зависят от конкретного языка программирования. В част-114Глава 2. Связьности, приложение может быть создано из объектов, написанных на различныхязыках программирования.При работе с объектами времени исполнения тот способ, которым они будутреализованы, обычно остается открытым.
Так, например, разработчик может решить написать на С библиотеку, содержащую набор функций, которые смогутработать с общим файлом данных. Главный вопрос состоит в том, как превратить эту реализацию в объект, методы которого будут доступны с удаленной машины. Традиционный способ состоит в том, чтобы использовать адаптер объектов{object adapter), который послужит оболочкой {wrapper) реализации с единственной задачей — придать реализации видимость объекта. Сам термин «адаптер»взят из шаблона проектирования, описанного в [157], который предоставляет интерфейс, преобразуемый в то, что ожидает клиент. Примером адаптера объектовможет быть некая сущность, динамически привязываемая к описанной ранеебиблиотеке на С и открывающая файл данных, соответствующий текущему состоянию объекта.Адаптеры объектов играют важную роль в объектных распределенных системах.
Чтобы сделать оболочку как можно проще, объекты определяются исключительно в понятиях интерфейсов, которые они реализуют. Реализация интерфейса регистрируется в адаптере, который, в свою очередь, создает интерфейсдля удаленных обращений. Адаптер будет принимать приходящие обращенияи создавать для клиентов образ удаленного объекта.
Мы вернемся к вопросаморганизации серверов и адаптеров объектов в следующей главе.Сохранные и нерезидентные объектыПомимо деления на объекты, зависящие от языка программирования, и объектывремени выполнения существует также деление на сохранные и нерезидентныеобъекты. Сохранный объект {persistent object) — это объект, который продолжаетсуществовать, даже не находясь постоянно в адресном пространстве серверногопроцесса.
Другими словами, сохранный объект не зависит от своего текущего сервера. На практике это означает, что сервер, обычно управляющий таким объектом,может сохранить состояние объекта во вспомогательном запоминающем устройстве и завершить свою работу. Позже вновь запущенный сервер может считатьсостояние объекта из запоминающего устройства в свое адресное пространствои обработать запрос на обращение к объекту. В противоположность ему, нерезидентный объект {transient object) — это объект, который существует, только покасервер управляет им.
Когда сервер завершает работу, этот объект прекращает существовать. Использовать сохранные объекты или нет — это спорный вопрос.Некоторые полагают, что нерезидентных объектов вполне достаточно. Сейчас мыне будем вдаваться в детали и вернемся к этому вопросу, когда будем обсуждатьобъектные распределенные системы в главе 9.2.3.2. Привязка клиента к объектуИнтересная разница между традиционными системами RPC и системами, поддерживающими распределенные объекты, состоит в том, что последние обычно2.3.
Обращение к удаленным объектам115предоставляют ссылки на объекты, уникальные в пределах системы. Такие ссылки могут свободно передаваться между процессами, запущенными на различныхмашинах, например как параметры обращения к методу. Путем сокрытия истинной реализации ссылок на объекты (то есть обеспечения их непрозрачности)и может быть даже использования их в качестве единственного средства обращения к объектам прозрачность распределения по сравнению с традиционным механизмом RPC повышается.Когда процесс хранит ссылку на объект, перед обращением к любому из методов объекта процесс должен в первую очередь выполнить привязку к этому объекту.
Результатом привязки будет заместитель, размещаемый в адресном пространстве процесса и реализующий интерфейс с методами, к которым обращаетсяпроцесс. Во многих случаях привязка осуществляется автоматически. Когда базовая система получает ссылку на объект, ей требуется способ отыскать сервер,управляющий этим объектом, и поместить заместителя в адресное пространствоклиента.При неявной привязке {implicit binding) клиенту предоставляется простой механизм, позволяющий напрямую запрашивать методы, используя только ссылкуна объект. Так, например, в C++ можно переопределить унарный оператор выбора (->) для класса так, чтобы он позволял обращаться со ссылками на объектыкак с простыми указателями (листинг 2.1). В случае неявной привязки клиентпрозрачно связывается с объектом в момент разрешения ссылки и полученияэтого объекта в действительности.
С другой стороны, в случае явной привязке{explicit binding) клиент должен до обращения к методам вызвать специальнуюфункцию для привязки к объекту. При явной привязке обычно возвращается указатель на локально доступный заместитель, как показано в листинге 2.2.Листинг 2.1. Пример неявной привязки с использованием только глобальныхпеременных// Определить внутрисистемную ссылку на объектD1str_object* obj_ref;// Инициализировать ссылку на распределенный объектobj_ref = . .
. :// Неявно провести привязку и обратиться к методуobj_ref->clo_someth1ng():Листинг 2.2. Пример явной привязки с использованием как глобальных,так и локальных переменных/7 Определить внутрисистемную ссылку на объектD1str_object obj_ref;// Определить указатель на локальные объектыLocal_object* obj_ptr:// Инициализировать ссылку на распределенный объектobj_ref = . . . ;// Явно провести привязку и получить указатель// на локальный заместительobj_ptr = b1ncl(obj_ref):// Обратиться к методу локального заместителяobj_ptr->clo_something();116Глава 2.