Источник:
Распределенные системы. Принципы и парадигмы.
Э. Таненбаум, М. ван Стеен.
Распределённые системы объектов. DCOM. (Данная статья)


Распределённые системы объектов. DCOM.

Вторая распределенная система объектов, которую мы рассмотрим, — это распределенная модель СОМ (Distributed СОМ, DCOM) корпорации Microsoft. Как можно понять PI3 ее названия, модель DCOM выросла из модели компонентных объектов (Component Object Model, COM). COM — это технология, лежащая в основе различных версий операционных систем Windows от Microsoft, начиная с Windows 95. В противоположность CORBA, DCOM не является результатом деятельности комитета. Это, в частности, видно из того факта, что существует всего лишь 300-страничное черновое описание СОМ, датированное октябрем 1995 года [292]. К сожалению, то, что модель DCOM избежала обсуждения в комитете, повлекло за собой отсутствие хорошо спроектированной архитектуры с минимальным набором базовых элементов, из которых строятся компоненты и службы. Наоборот, в настоящее время DCOM — крайне запутанная система, в которой множество сходных действий выполняются множеством разных способов, и подобное сосуществование различных решений временами кажется невозможным.

Критиковать модель DCOM нетрудно. Однако сравнивая ее с CORBA, можно обоснованно утверждать, что DCOM — это технология, которая в значительной степени доказала свое право на существование. Десятки миллионов человек каждый день используют Windows в сетевой среде, а значит, DCOM — широко распространенная система. В этом смысле CORBA или любым другим распределенным системам до нее еще идти и рщти.

Далее мы рассмотрим наиболее важные части DCOM, следуя тому же порядку изложения материала, которого мы придерживались при изучении CORBA. Чтобы понять, что такое DCOM, лучше всего обратиться к одной из книг для программистов, такой как [357] или [386]. Хорошее введение в различные технические аспекты DCOM имеется в [132]. Обзор DCOM с точки зрения распределенной модели Windows 2000 можно найти в [92].

Обзор

Как уже упоминалось, модель DCOM базируется на модели СОМ. Целью создания СОМ была поддержка разработки компонентов, которые могли бы динамически активизироваться и взаимодействовать друг с другом. Компонент в СОМ — это исполняемый код, содержащийся в динамически компонуемой библиотеке (DLL) или исполняемой программе.

Сама по себе модель СОМ существует в виде библиотек, компонуемых с процессом. Изначально она разрабатывалась для поддержки так называемых составных документов (compound documents). Как мы говорили в главе 3, составные документы — это документы, построенные из разнородных частей, таких как текст (форматированный), изображения, электронные таблицы и т. п. Каждая из этих частей может быть отредактирована при помощи ассоциированного с ней приложения.

Для поддержки бесчисленного множества составных документов Microsoft нужен был обобщенный метод для разделения отдельных частей и объединения их в единую сущность. Вначале это привело к технологии связывания и внедрения объектов (Object Linking and Embedding, OLE), Первая версия OLE использовала для передачи информации между частями документа примитивный и негибкий способ обмена сообщениями. Вскоре она была заменена следующей версией, также называвшейся OLE, но построенной на базе более гибкого механизма СОМ, что привело к появлению структуры, представленной на рис. 9.17.

Рис. 9.17. Общая структура ActiveX, OLE и COM

На рисунке также показан элемент ActiveX — этим термином в настоящее время называют все, что относится к OLE, плюс некоторые новшества, к которым относят гибкую (как правило) способность компонентов выполняться в разных процессах, поддержку сценариев и более или менее стандартную группировку объектов в так называемые элементы управления ActiveX. Среди экспертов по DCOM (даже внутри Microsoft) не существует согласия по вопросу о точном определении ActiveX, поэтому мы даже не будем пытаться дать подобное определение.

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

Объектная модель

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

Как и в CORBA, объектная модель в DCOM построена на реализации интерфейсов. Грубо говоря, объект DCOM — это просто реализация интерфейса. Один объект может реализовывать одновременно несколько интерфейсов. Однако в отличие от CORBA в DCOM имеются только бинарные интерфейсы (binary interfaces). Такой интерфейс, в сущности, представляет собой таблицу с указателями на реализации методов, которые являются частью интерфейса. Разумеется, для определения интерфейса по-прежнему удобно использовать специальный язык определения интерфейса (IDL). В DCOM также имеется такой язык под названием MIDL (Microsoft IDL — язык IDL от Microsoft), при помощи которого генерируются бинарные интерфейсы стандартного формата.

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

Рис. 9.18. Разница между интерфейсами, определяемыми для каждого конкретного языка, и бинарными интерфейсами

Каждый интерфейс в DCOM имеет уникальный 128-битный идентификатор, который называется идентификатором интерфейса (Interface Identifier, IID), Каждый I ID абсолютно уникален, не существует двух интерфейсов с одинаковым идентификатором IID. Этот идентификатор создается путем комбинирования большого случайного числа, локального времени и адреса сетевого интерфейса текущего хоста. Вероятность того, что два сгенерированных индикатора совпадут, практически равна нулю.

Объект DCOM создается как экземпляр класса. Чтобы создать такой объект, необходимо иметь доступ к соответствующему классу. Для этой цели DCOM содержит объекты класса (class objects). Формально таким объектом может быть все, что поддерживает интерфейс IClassFactory. Этот интерфейс содержит метод Createlnstance, который похож на оператор new в языках C++ и Java. Вызов метода Createlnstance для объекта класса приводит к созданию объекта DCOM, содержащего реализацию интерфейсов объекта класса.

Таким образом, объект класса представляет собой коллекцию объектов одного типа, то есть реализующих один и тот же набор интерфейсов. Объекты, принадлежащие к одному классу, обычно различаются только в части текущего состояния. Путем создания экземпляров объекта класса становится возможным обращение к методам этих интерфейсов. В DCOM на любой объект класса можно сослаться по его глобальному уникальному идентификатору класса (Class Identifier, CLSID).

Все объекты реализуют стандартный объектный интерфейс lUnknown. Когда путем вызова Createlnstance создается новый объект, объект класса возвращает указатель на этот интерфейс. Самый важный метод, содержащийся в lUnknown, — метод Querylnterface, который на основании IID возвращает указатель на другой интерфейс, реализованный в объекте.

Важное отличие от объектной модели CORBA состоит в том, что все объекты в DCOM нерезидентные. Другими словами, как только у объекта не остается ссылающихся на него клиентов, этот объект удаляется. Подсчет ссылок производится путем вызова методов AddRef и Release, входящих в интерфейс lUnknown. Наличие исключительно нерезидентных объектов делает невозможным хранение каждым из объектов своего глобально уникального идентификатора. По этой причине объекты в DCOM могут вызываться только по указателям на интерфейсы. Соответственно, как мы увидим позднее, для передачи ссылки на объект другому процессу необходимо предпринять специальные меры.

DCOM также требует динамического обращения к объектам. Объекты, запросы к которым могут создаваться динамически, во время выполнения, должны иметь реализацию интерфейса IDispatch. Этот интерфейс подобен интерфейсу динамического обращения (DII) в системе CORBA.

Библиотека типов и системный реестр

Эквивалент хранилища интерфейсов CORBA в DCOM называется библиотекой типов (type library). Библиотека типов обычно ассоциируется с приложением или другим крупным компонентом, содержащим различные объекты классов. Сама по себе библиотека может храниться в отдельном файле или быть частью приложения. В любом случае библиотека типов в первую очередь требуется для точного описания сигнатуры динамически вызываемых методов. Кроме того, библиотеки типов могут использоваться в системах программирования, например, для отображения структуры разрабатываемых интерфейсов на экране.

Для того чтобы действительно активизировать объект, то есть гарантировать, что он создан и помещен в процесс, из которого будет в состоянии принимать обращения к методам, DCOM использует реестр Windows в комбинации со специальным процессом — менеджером управления службами (Service Control Manager, SCM). Кроме всего прочего, реестр используется для записи отображения идентификаторов классов (CLSID) на локальные имена файлов, содержащих реализации классов. Чтобы создать объект, процесс сначала должен убедиться, что соответствующий объект класса загружен.

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

Общая архитектура DCOM, включая объекты классов, реальные объекты и заместители, представлена на рис. 9.19 [105]. Процесс клиента получает доступ к SCM и реестру, что помогает ему найти удаленный объект и выполнить привязку к нему. Клиенту предлагается заместитель, реализующий интерфейсы этого объекта.

Рис. 9.19. Общая архитектура DCOM

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

Службы DCOM

Модель DCOM можно рассматривать как расширенную за счет добавления средств сообщения с удаленными объектами модель СОМ. Однако СОМ и сама по себе стала иной, и новая ее версия называется СОМ+. Модель СОМ+ тоже можно рассматривать как расширенный вариант модели СОМ, содержащий различные службы, которые ранее были полезными дополнениями к СОМ. Так, в частности, СОМ+ включает расширения, которые позволяют серверу успешно поддерживать одновременно несколько объектов. Кроме того, добавлены службы, реализуемые на внешних серверах, например системы очередей сообщений.

Провести черту между СОМ, DCOM, СОМ+ и внешними службами часто бывает затруднительно, и подобные попытки лишь способствуют путанице. Далее мы будем просто ссылаться на DCOM как на расширение, включающее и СОМ, и СОМ+, и ActiveX. Там, где это возможно и имеет смысл, мы будем разделять службы, просто помогающие DCOM, и компоненты, фактически являющиеся частями DCOM. Чтобы понять, какие службы непосредственно входят в DCOM, рассмотрим табл. 9.4, в которой перечислены службы CORBA и соответствующие им службы DCOM. Также в этой таблице приводятся службы Windows 2000, обычно доступные клиентам модели DCOM, но не являющиеся ее частями.

Таблица 9.4. Обзор служб CORBA, DCOM в Windows 2000

Ниже мы рассмотрим большую часть этих служб. Следует отметить, что сама по себе модель DCOM, в отличие от CORBA, не является законченной распределенной системой, поскольку требует наличргя внешнргх служб. Так, например, очевидно, что служба именования является неотъемлемой частью распределенной системы. Именование в Windows 2000 поддерживается при помощи службы Active Directory. Эта служба, в сущности, состоит из набора серверов каталогов LDAP, которые именуются и просматриваются при помощи системы DNS. Мы говорили о DNS и LDAP в главе 4. Однако Active Directory не является частью DCOM. Соответственно, при запуске приложений DCOM в среде UNIX эти приложения не в состоянии использовать ту же самую службу именования, что и в среде Windows 2000. У переносимости всегда есть некоторые границы.

Очевидно, что подобный подход препятствует межоперационной совместимости. С другой стороны, учитывая, что фактически все приложения DCOM рассчитаны на работу в среде Windows, непонятно, насколько этот недостаток совместимости действительно можно считать проблемой.

Связь

Как и в CORBA, в базовом варианте DCOM поддерживает только синхронное взаимодействие: клиент обращается к объекту и блокируется до получения ответа. Синхронные обращения такого рода поддерживаются в системе по умолчанию. Однако, как мы увидим далее, DCOM обслуживает также и другие формы взаимодействия.

Модели обращения к объектам

Как мы говорили, синхронные обращения являются стандартными для DCOM. Если что-нибудь пойдет не так, как ожидалось (а в распределенных системах это обычное дело), клиент получает код ошибки. DCOM не может самостоятельно повторить обращение к объекту, поскольку использует семантику «максимум однажды».

Одно из самых ранних расширений «чистых» синхронных обращений — интерфейсы обратного вызова. Интерфейсы обратного вызова поддерживаются связующими объектами (connectable objects). Это специальные объекты DCOM, которые могут содержать указатели на интерфейсы обратного вызова, реализуемые клиентами. Связующрп! объект описывает интерфейс обратного вызова, реализацию которого он ожидает найти на стороне клиента. Когда клиент выполняет привязку к связующему объекту, он должен предоставить ему указатель на интерфейс обратного вызова. Если связующий объект находится на удаленном хосте, для передачи ему указателя на интерфейс сначала нужно выполнить мар- шалинг. Маршалинг указателей на интерфейсы мы рассмотрим чуть ниже.

После появления модели СОМ+ и интеграции ее в систему Windows 2000 в DCOM появилась поддержка и других моделей обращения. Одно из таких расширений — возможность отмены затянувшегося синхронного вызова. Когда поток выполнения А начинает синхронное обращение, создается объект отмены (cancel object), реализующий метод Cancel. Этот метод может быть вызван из другого потока выполнения В с передачей в качестве параметра идентификатора потока выполнения А. В результате поток выполнения А будет немедленно разблокирован.

Также поддерживаются и асинхронные вызовы, соответствующие модели опроса CORBA для асинхронного обращения к методам. На самом деле, подход, связанный с созданием интерфейсов, поддерживающих асинхронные вызовы. имеет определенные отличия от модели опроса С ORB А. Взяв за отправную точку описание интерфейса на MIDL, компилятор MIDL для каждого метода т в этом интерфейсе генерирует два других метода — Begin_m и Finish_m. Первый из них содержит только входные параметры метода m, а второй — только его выходные параметры.

Клиент начинает взаимодействие с вызова метода Begin_m, после чего немедленно продолжает свою работу. Для объекта нет никакой разницы между синхронными и асинхронными вызовами, единственное, что он может увидеть, — это обращение к методу m. Результаты этого обращения пересылаются обратно клиенту, где буферизуются до момента вызова клиентом метода Finish_m.

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

События

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

DCOM средствами СОМ+ поддерживает более сложную (и более практичную) модель событий, известную под названием систем публикации/подписки (publish/subscribe systems). Мы будем ее обсуждать в главе 12. Основная идея примерно та же, что и в модели продвижения сообщений CORBA. Событие моделируется путем вызова метода, имеющего только входные параметры. События группируются в класс событий (event class), который представляет собой обычный объект класса DCOM со своим идентификатором CLSID. Нет никакой необходимости реализовывать класс событий самостоятельно: в DCOM для него имеется стандартная реализация. После создания экземпляра класса событий поставщик событий может просто генерировать их вызовом соответствующих методов этого объекта. Отметим, что само событие объектом не является.

Подписка на события также проста. Предположим, что событие представлено методом m_event. Подписчик поддерживает реализацию этого метода. Для подписки на событие он передает указатель на интерфейс, реализующий этот метод, в систему событий. Таким образом, когда поставщик вызывает m_event, система событий отвечает за то, чтобы при этом произошли также обращения к версии m_event каждого подписчика. Рисунок 9.20 иллюстрирует принципы, лежащие в основе механизма событий DCOM. Очевидно, этот подход действительно похож на продвижение событий в системе CORBA.

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

Рис. 9.20. Обработка событий в DCOM

Передача сообщений

Кроме нерезидентной асинхронной связи DCOM также поддерживает и сохранную асинхронную связь, используя для этого компоненты очередей (Queued Components, QC), QC — это на самом деле интерфейс к системе очередей сообщений Microsoft (Microsoft Message Queuing, MSMQ), очень похожей на систему MQSeries компании IBM, которую мы обсуждали в главе 2. Назначение QC — полностью скрыть MSMQ и от клиентов, и от объектов. Взамен им предоставляются точно такие же обращения к методам, как и при асинхронных вызовах, о которых мы уже говорили. Основная деятельность компонентов очередей происходит следующим образом.

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

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

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

MSMQ, как и большинство систем очередей сообщений (например, MQSeries), поддерживает транзащионные очереди (transactional queues). В своей простейшей форме транзакционная очередь состоит из коллекции сообщений, которая передается в другую очередь (или к месту назначения) либо вся целиком, либо не передается ни одно из сообщений. Кроме того, транзакционная очередь гарантирует восстановление сообщений после сбоя. Существуют также и более совершенные формы транзакций, при которых операции в одной транзакцион- ной очереди представляют собой на самом деле вложенную транзакцию большой распределенной транзакции. В таких случаях применяются выделенные координаторы, о которых мы говорили в главе 7.

Процессы

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

Клиенты

Поддержка клиента в модели DCOM — это ее естественное предназначение. Для клиента все выглядит почти так, как если бы работающий объект находился в его собственном адресном пространстве. Другими словами, объекты создаются и вызываются точно так же, как это делалось до появления DCOM, когда существовала только модель СОМ.

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

Как процесс А может передать ссылку на объект другому процессу, скажем В? Понятно, что пересылка его указателя на интерфейс к успеху не приведет. Процессу В нужен, в сущности, указатель на реализацию того же интерфейса, который имеется у процесса А. Этот интерфейс имеет уникальный идентификатор — HD. Другими словами, для передачи указателя на интерфейс на самом деле необходимо передать HD этого интерфейса. Кроме того, процесс А может передать В информацию о привязке и об используемом транспортном протоколе. Предполагая, что процесс В имеет локальную реализацию заместителя для переданного ему интерфейса, он может просто загрузить эту реализацию и инициировать вызов нужного метода.

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

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

По существу, передача ссылки на объект в случае пользовательского маршалинга происходит путем маршалинга заместителя, принадлежащего отправителю, передачи этого заместителя получателю и последующего демаршалинга полученного заместителя из сообщения. То есть заместитель отправителя в конечном итоге оказывается у получателя. Отметим, что подобный подход очень похож на передачу ссылок на объекты в Java, о которой мы говорили в главе 2. Поскольку маршалинг выполняется способом, специфичным для данного объекта, необходимо, чтобы процесс-получатель имел соответствующий код для демаршалинга пришедшего потока байтов, представляющего собой, по сути, заместителя после маршалинга (то есть после своего рода упаковки). Предполагается, что этот код доступен получателю и идентифицируется по его идентификатору CLSID. Передачу ссылки на объект в DCOM иллюстрирует рис. 9.21.

Рис. 9.21. Передача ссылки на объект в DCOM при пользовательском маршалинге

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

Серверы DCOM

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

На хосте, поддерживающем объекты DCOM, должен выполняться уже упоминавшийся ранее менеджер управления службами (Service Control Manager, SCM). SCM отвечает за активизацию объектов, которая производится следующим образом. Предположим, что клиент владеет CLSID объекта класса. Чтобы создать новый объект, он передает этот идентификатор CLSID в свой локальный реестр, где выполняется поиск хоста, на котором должен находиться нужный сервер объектов. Затем CLSID передается менеджеру SCM, ассоциированному с найденным хостом. В поисках файла, позволяющего загрузить объект класса, который может создавать экземпляры нового объекта, SCM ищет этот идентификатор CLSID уже в своем локальном реестре.

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

Такой подход оставляет решение всех вопросов, связанных с управлением объектами на сервере, разработчику. Чтобы немного облегчить ему жизнь, DCOM предоставляет средства управления объектами. Одно из таких средств носит название активизации «на лету» («just-in-time» activation), или JIT-активизации (JIT-activation). Под этим названием скрывается механизм, при помощи которого сервер может управлять активизацией и удалением объектов. Он работает следующим образом.

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

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

Именование

Модель DCOM сама по себе предоставляет объектам лишь относительно низкоуровневые средства именования. Ранее мы уже обсуждали, каким образом в качестве примитивных ссылок на объекты можно использовать указатели на интерфейсы. Указатель на интерфейс имеет смысл только в тех процессах, в которых он используется и может быть в любой момент удален процессом. В добавление к указателям на интерфейсы DCOM предоставляет также ссылки на сохранные объекты, которые могут совместно использоваться несколькими процессами. Эти ссылки, известные под названием моникеров (monikers), мы и обсудим. DCOM не имеет высокоуровневой службы именования. Однако, являясь частью операционной системы Windows 2000, объекты DCOM могут пользоваться службой Active Directory Windows, которая является настоящей службой каталогов. Здесь мы также рассмотрим и эту службу.

Моникеры

В противоположность CORBA базовая объектная модель DCOM поддерживает только нерезидентные объекты. Другими словами, когда в объекте больше нет надобности, он удаляется. Чтобы продлить жизнь объекта, когда его перестанет использовать последний клиент, в DCOM применяются сохранные ссылки. Подобная ссылка, называемая в DCOM моникером, может быть сохранена на диске. Моникер содержит всю информацию, необходимую для воссоздания соответствующего объекта и приведения его в то состояние, которое он имел перед тем, как его перестал использовать последний клиент.

DCOM предоставляет различные варианты моникеров. Наиболее важным из них является файловый моникер (file moniker), ссылающийся на объект, создаваемый из файла локальной файловой системы. В этом случае моникер должен содержать полное имя файла, используемого для создания объекта. Кроме того, он должен содержать также CLSID объекта класса, необходимого для создания объекта этого класса.

Как и все моникеры, файловый моникер поддерживает операцию BindToObject, вызываемую клиентом для привязки к объекту, с которым связан моникер. Порядок привязки в случае файлового моникера иллюстрирует табл. 9.5.

Таблица 9.5. Привязка к объекту DCOM при помощи файлового моникера

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

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

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

И, наконец, клиенту возвращается указатель на изначально запрошенный им интерфейс, что и завершает операцию привязки.

В качестве побочного результата привязки моникер регистрирует связанный с ним объект в таблице запущегшых объектов (Running Object Table, ROT) клиентской машины. Когда бы другой клиент ни использовал моникер для привязки к объекту, указанному ссылкой, моникер первым делом ищет этот объект в ROT. Если он обнаруживает, что объект класса уже создан, он выполняет привязку клиента к этому экземпляру. Таким образом, достигается совместное использование объектов разными процессами, работающими на одной и той же машине.

Кроме файловых моникеров DCOM поддерживает несколько других типов моникеров, некоторые из них представлены в табл. 9.6. Кроме этих заранее определенных типов моникеров можно также создавать пользовательские моникеры. Детальное описание вопросов, связанных с реализацией моникеров, можно найти в [132].

Таблица 9.6. Типы моникеров, определенные в DCOM

Active Directory

С появлением Windows 2000 приложения DCOM получили возможность использовать полноценную глобальную службу каталогов, известную под названием Active Directory. Напомним, что служба каталогов позволяет клиентам производить поиск некоторых сущностей на основании заданного набора их свойств. Так, например, служба каталогов может вернуть имена всех web-серверов, работающих под UNIX. В этом смысле службу каталогов можно сравнить с «желтыми страницами». В противоположность ей служба именования, способная выдать информацию только на основе полного имени, сравнима с обычной телефонной книгой.

До появления Active Directory в различных компонентах DCOM и Windows поддерживались разные службы именования и каталогов, такие как реестр, библиотеки типов, моникеры и т. д. Хотя служба Active Directory на самом деле не является частью DCOM, будет полезно кратко описать ее организацию и методы использования для именования и поиска объектов.

По организации служба Active Directory в значительной степени соответствует распределенной системе на базе Windows 2000. Как предполагается, такая система разделена на домены (domains), каждый из которых содержит некоторое количество пользователей и ресурсов. В каждом из доменов имеется один или несколько контроллеров домена (domain controllers), которые представляют собой локальные серверы каталогов, контролирующие пользователей и ресурсы этого домена. Домен имеет соответствующее имя DNS, например cs.vu.nl.

Контроллеры домена представляют собой серверы каталогов LDAP. Как мы уже говорили в главе 4, протокол LDAP представляет собой Интернет-версию протокола доступа к каталогам Х.500. В случае Active Directory каждый контроллер домена содержит заранее определенную схему организации сущностей и их атрибутов. Существуют, например, предопределенные записи для регистрации пользователей, хостов, принтеров и т. п. При необходимости эта схема может быть расширена.

Контроллеры доменов регистрируются в DNS как службы LDAP с использованием записей типа SRV системы DNS, описанных в главе 4. Так, сервер LDAP домена cs.vu.nl может быть зарегистрирован при помощи записи SRV под именем ldap.tcp.cs.vu.nl. Это имя может, в свою очередь, ссылаться на имя DNS хоста соответствующего контроллера домена.

Теперь понятно, что найти в заданном домене контроллер домена очень легко. Клиент должен просто запросить у DNS имя хоста сервера LDAP в этом домене, после чего он сможет связаться с этим сервером и получить информацию о пользователях и ресурсах или запросить данные о произошедших рхзменениях. Эта схема в общем виде приведена на рис. 9.22.

Рис. 9.22. Обобщенная организация Active Directory

Одна из проблем описанного варианта построения службы каталогов состоит в том, что клиент до начала поисков должен знать нужный ему домен. Так, например, если клиент хочет найти все web-серверы, работающие под UNIX, он должен сначала связаться с контроллером некоего конкретного домена и лишь после этого посылать ему поисковый запрос. Если поиск распространяется на несколько доменов, клиент должен связываться с контроллерами каждого домена по отдельности, а затем объединить полученные результаты.

Чтобы помочь справиться с этой проблемой. Active Directory позволяет группировать домены в деревья и леса. Дерево доменов (domain tree) представляет собой поддерево пространства имен DNS, а лес доменов (domain forest) — это просто группы независимых доменов. Преимущество группировки доменов состоит в том, что служба Active Directory создает для всей группы единый глобальный индекс, именуемый глобальным каталогом (global catalog). Записи каждого домена группы вместе с наиболее важными парами (атрибут, значение) копируются в каталог. Клиенту теперь значительно проще сделать поисковый запрос в каталог группы доменов.

Дополнительную информацию о Active Directory, управлении этой системой, настройке конфигурации, репликации и правил защиты, можно найти в [273].

Синхронизация

Базовый механизм синхронизации в DCOM реализован в форме транзакций. Этот механизм мы рассмотрим чуть позже при обсуждении вопросов отказоустойчивости в DCOM.

Репликация

Стандартной поддержки репликации в приложениях DCOM не существует. Реп- лршация может осуществляться только при помощи специальных служб, таких как Active Directory. Что касается пользовательских приложений, разработчику придется разрабатывать собственные решения.

Отказоустойчивость

В основном отказоустойчивость в DCOM обеспечивается при помощи автоматических транзакций (automatic transactions), которые представляют собой неотъемлемую часть СОМ+. Автоматические транзакции позволяют разработчику определить набор обращений к методам, в том числе к методам различных объектов, которые нужно объединить в транзакцию. Также можно представить в виде транзакции и одиночное обращение к методу. Этот вариант используется в том случае, когда реализация метода предполагает работу с базой данных.

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

Таблица 9.7. Значения атрибута транзакции объектов DCOM

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

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

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

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

И, наконец, если объект показывает, что поддержка транзакций отключена (DISABLED), то вне зависимости от пожеланий клиента объект не будет участвовать в транзакциях. Отключение транзакций ~ это более жесткий вариант, чем просто отсутствие поддержки. В последнем случае клиент, от которого исходит обращение, может попытаться включить в транзакцию объект, к которому это обращение направлено. Если поддержка транзакций отключена, это невозможно.

Вообще говоря, автоматические транзакции обычно реализуются при помощи отдельного менеджера транзакций. Во многих случаях используется менеджер транзакций Windows, известный как координатор распределенных транзакций (Distributed Transaction Coordinator, DTC) корпорации Microsoft. DTC — это относительно стандартный менеджер транзакций, реализующий протокол двухфазного подтверждения, описанный в главе 7.

Защита

Как и в CORBA, система защиты DCOM в основном обеспечивает защиту обращений к объектам. Однако способ реализации защищенных обращений здесь абсолютно иной. Хотя DCOM чаще всего входит в одну из операционных систем семейства Windows, разработчики DCOM совершенно оправданно решили по возможности отделить защиту DCOM от служб защиты Windows. Таким образом они сохранили возможность реализации DCOM на других операционных системах с сохранением защиты обращений.

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

Декларативная защита

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

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

DCOM поддерживает несколько уровней аутентификации (authentication levels), представленных в табл. 9.8. По умолчанию большинство систем считают достаточной аутентификацию, происходящую в ходе первого контакта клиента с сервером (уровень CONNECT). Однако можно также требовать идентификации при каждом обращении к серверу (CALL) или даже при каждом получении данных от клиента (PACKET). Уровни PACKET_INTEGRITY и PACKET_PRIVACY - это уже не просто уровни аутентификации, а скорее добавление к уровню PACKET проверки целостности и конфиденциальности соответственно.

Таблица 9.8. Уровни аутентификации в DCOM

Чтобы защитить клиента от злонамеренных действий сервера, можно определить, в какой степени сервер имеет право присвоить себе роль или мандат клиента, обращающегося к объекту (табл. 9.9). Для этого используются так называемые уровни обезличивания (impersonation levels). Если уровень обезличивания имеет значение ANONYMOUS, сервер не может определить, кто именно к нему обращается, а значит, не может каким-либо образом выступать от имени клиента.

Таблица 9.9. Уровни обезличивания в DCOM

Если клиент хочет получить доступ к ресурсам, он должен позволить серверу осуществлять контроль доступа, что требует уровня обезличивания IDENTIFY. Этот уровень позволяет серверу идентифицировать клиента, однако эта идентификация может использоваться только на этом сервере и только для проверки наличия у клиента необходимых прав доступа.

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

Программная защита

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

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

У программной защиты имеется интересная черта: процесс может также указать и службу защиты, которую он хочет использовать для обеспечения защиты. Обычно эта служба относится к той операционной системе, поверх которой работает DCOM. DCOM различает пять служб аутентификации, представленных в табл. 9.10, а также три службы авторизации, перечисленные в табл. 9.11. Число служб в обоих случаях легко увеличить. Наличие или отсутствие конкретной службы зависит не от DCOM, а от операционной системы. Так, например, в Windows 2000 обычно доступны такие службы, как SSL и версия Kerberos с асимметричной криптосистемой.

Таблица 9.10. Стандартные службы аутентификации, поддерживаемые DCOM
Таблица 9.11. Стандартные службы авторизации, поддерживаемые DCOM

Так настроить параметры активизации, чтобы клиент получил возможность создавать экземпляры объекта, невозможно. Эту информацию можно только декларировать, поскольку SCM машины, на которой создается объект, всегда проверяет реестр, чтобы убедиться, что привилегии клиента соответствуют активизации. Однако можно делегировать право на активизацию другому процессу. Детали можно найти в [132].


Источник:
Распределенные системы. Принципы и парадигмы.
Э. Таненбаум, М. ван Стеен.
Распределённые системы объектов. DCOM. (Данная статья)