Механизм удаленного вызова процедур (Remote Procedure Call или RPC) является ключевой технологией, используемой при построении распределенных приложении. RPC позволяет приложению выполнять процедуры на другой машине в сети. При этом механизм RPC скрывает от разработчика детали сетевого взаимодействия при удаленных вызовах и может использоваться в сетях, построенных с использованием различных архитектур.

В данной статье производится обзор двух наиболее известных на сегодняшний день механизмов удаленных вызовов процедур:

1. DCE RPC (Distributed Computing Environment Remote Procedure Call), разработанного консорциумом Open Software Foundation. Этот стандарт полностью поддерживается такими производителями как IBM, Hewlett Packard, Digital Equipment. Компания Microsoft реализовала этот стандарт с некоторыми изменениями. Но для Windows 95/NT существуют реализации PC-DCE, доступные от компаний IBM и Gradient.

2. ONC RPC (Open Network Computing Remote Procedure Call), разработанного корпорацией Sun Microsystems. Этот стандарт является доработкой одного из первых механизмов удаленных вызовов, разработанных Xerox в начале 80-ых [2]. ONC RPC механизм встроен в ОС Solaris.

В заключение статьи производится сравнение двух этих механизмов.

1. Механизм удаленного вызова процедур DCE RPC консорциума Open Software Foundation

В первой части описывается механизм удаленных вызовов процедур (Remote Procedure Call или RPC), который является частью стандарта распределенной среды (Distributed Computing Environment или DCE), разработанного консорциумом Open Software Foundation [1].

DCE RPC предоставляет программисту два основных компонента, необходимых для построения распределенных приложений, в которых используются удаленные вызовы:

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

Дальнейшее рассмотрение DCE RPC представляет собой развернутое описание этих компонент.

Модель клиент-сервер

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

В основе архитектуры клиент-сервер лежит модель распределенных ресурсов, реализуемая на основе механизма удаленных вызовов. В модели клиент-сервер приложение разбивается на две части: клиентскую и серверную.

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

Удаленные вызовы как расширения локальных.

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

Таким образом, расширение семантики локальных вызовов заключается в следующем:

(1) Обеспечение независимости от транспортного протокола и прозрачности.

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

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

Различные транспортные протоколы предоставляют различные уровни надежности. Механизм удаленных вызовов учитывает, какой транспортный протокол используется.

Спецификация DCE RPC включает описание семантики выполнения, которая определяет, сколько раз операция, вызванная клиентом, может выполняться на стороне сервера. Такой контроль над числом выполнений операции при одном вызове необходим при использовании ненадежного транспортного протокола.

Стандарт DCE RPC включает описание следующих разновидностей семантики выполнения:

а) семантика - "не более раза"

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

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

б) семантика - "одинакового воздействия"

При использовании этой семантики операция может быть выполнена более одного раза.

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

в) семантика - "возможно"

При использовании данной семантики клиент не ждет и не получает результат выполнения операции или код ошибки. Таким образом, операции, при вызове которых используется семантика "возможно", не должны применяться для получения значений от сервера.

При использовании семантики "возможно" автоматически применяется и семантика "одинакового воздействия".

г) семантика - "широковещания"

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

При использовании семантики "широковещания" автоматически применяется и семантика "одинакового воздействия".

Еще раз подчеркнем, что семантики "возможно" и "широковещания" являются специальными формами семантики "одинакового воздейсвия".

Для каждой операции интерфейса с помощью языка IDL можно определить, какая семантика будет использована при вызове этой операции. "Не более раза" является семантикой, используемой по умолчанию.

(2) Связывание.

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

(3) Отсутствие совместно используемого адресного пространства.

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

(4) Обработка ошибок.

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

(5) Представление данных при обмене между клиентом и сервером во время удаленного вызова.

Поскольку удаленные вызовы могут производиться в разнородных сетях, необходима стандартизация универсального представления данных для обмена между машинами, построенными на основе различных архитектур. Для этого используется протокол Network Data Representation (NDR), который машинно-зависимое представление данных, используемых при удаленном вызове, в поток октетов (т.е. в последовательность восьмибитовых элементов). В протоколе RPC протокол NDR применяется для пересылки параметров удаленного вызова и его результата. Важно отметить, что предусмотрена возможность пересылки данных между машинами, построенными на одной архитектуре, без преобразования данных к универсальному представлению. Кроме того, протокол NDR дает возможность использования каналов (pipes) для пересылки последовательности однотипных элементов, количество которых определяется динамически и потенциально не ограничено. Это очень полезная возможность отсутствует во многих других протоколах, используемых для пересылки данных.

(6) Защита.

За счет интеграции со службой защиты (служба аутентификации) производится контроль санкционированности вызова клиентом серверных операций. Интерфейс доступа к службе защиты фиксируется стандартом DCE RPC. Таким образом, возможно использование различных служб защиты. Кроме того, возможно использование различных уровней защиты. Клиент и сервер определяют требуемую службу защиты и уровень защиты через параметры уделенного вызова.

Служба имен

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

Реализация сервера

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

Параллелизм сервера

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

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

Удаленное управление сервером

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

Приложение. Stub. Подсистема времени выполнения.

Рассмотрим взаимосвязь между компонентами RPC при выполнении удаленных вызовов.

Подсистема времени выполнения

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

RPC API (Application Programmer"s Interface) - это программный интерфейс для доступа к подсистеме времени выполнения. Подсистема времени выполнения взаимодействует с различными службами, такими как карта EP (endpoint), служба имен и службами, обеспечивающими защиту. RPC API также предоставляет интерфейс для доступа к этим службам, для выполнения операций, специфичных для удаленных вызовов процедур.

Stub

При разработке распределенных приложений, программист определяет интерфейс, используя язык определения интерфейсов (Interface Definition Language или IDL). При этом описываются заголовки функций, реализующих операции интерфейса. Синтаксис IDL подобен ANSI C, хорошо знакомому многим разработчикам, и поэтому легко осваивается. Язык IDL имеет дополнительные конструкции, с помощью которых описывается сетевое взаимодействие при удаленных вызовах, например, формат пересылки параметров или метод связывания при использовании данного интерфейса. Определение интерфейса, написанное на языке IDL, транслируется компилятором IDL в stub клиента и stub сервера, которые представляют собой программный код, используемый в клиентской и серверной частях приложения.

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

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

Приложение

В код приложений, использующих удаленные вызовы, входят

  • удаленные вызовы (на стороне клиента) и процедуры, реализующие операции интерфейса (на стороне сервера);
  • вызовы функций RPC API (используются как клиентом, так и сервером).

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

Вызовы функций RPC API непосредственно из приложения (т.е. не через stub) могут использоваться для контроля процесса связывания или для выполнения других функций; таким образом, достигается максимально гибкое взаимодействие между клиентом и сервером. Но использование функций RPC API необязательно в приложениях, использующих удаленные вызовы. Потребность их использования клиентом во много зависит от выбранного метода связывания (существующие методы перечисляются ниже).

Связывание

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

  • используемый транспортный протокол;
  • номер версии протокола RPC;
  • используемый протокол пересылки параметров и результата;
  • сетевой адрес сервера;
  • EP на этом сервере;
  • UUID объекта;
  • UUID интерфейса;
  • номер версии интерфейса;
  • номер операции в данном интерфейсе.

К информации связывания относятся первые пять элементов этого списка.

Замечание: Universal Unique Identifier или UUID - это уникальный в пространстве и во времени идентификатор, который используется для различных целей.

Под идентификатором интерфейса будет далее пониматься UUID интерфейса и номер версии интерфейса.

Связывание может быть частичным или полным. При частичном связывании используется четыре первых элемента списка (без EP), а при полном - пять первых элементов. Разница заключается в том, что при частичном связывании связь осуществляется с сервером, а при полном с конкретной EP на сервере.

Дескриптор связывания

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

Строка связывания

Строка связывания - это символьное представление информации связывания в читаемом для человека виде. Приложение может получить строку связывания от подсистемы времени выполнения, используя вызовы RPC API. Строка связывания может использоваться для установления связи между клиентом и сервером.

Шаги связывания

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

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

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

Рассмотрим кратко последовательность действий при связывании:

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

Разберем эту последовательность действий более подробно.

Шаги связывания на стороне сервера

Сервер выполняет ряд шагов для того, чтобы привести в состояние готовности к связыванию подсистему времени выполнения, службу имен и карту EP. Основной задачей сервера является создание EP и установление связей между элементами связывания.

На рисунке показаны связи, которые сервер должен установить, для того чтобы быть в состоянии принимать удаленные вызовы.

Как видно из рис.1, при этом используются следующие компоненты:

  • подcистема времени выполнения;
  • stub и код приложения;
  • карта EP;
  • служба имен.


Рис. 1. Взаимосвязь серверных компонентов связывания.

Рассмотрим подробно шаги связывания на стороне сервера (некоторые из них необязательны):

(1) Серверное приложение или stub для каждого менеджера определяет вектор указателей на его процедуры (Entry Point Vector - EPV). Напомним, что менеджер - это набор процедур, реализующих операции интерфейса, и сервер может иметь более одного менеджера для данного интерфейса. При удаленном вызове номер операции используется для выбора необходимого указателя на ее реализацию из EPV.

(2) Сервер регистрирует набор записей вида UUID объекта / UUID типа в подсистеме времени выполнения.

(3) Сервер регистрирует множество записей вида идентификатор интерфейса / UUID типа / EPV в подсистеме времени выполнения. В результате последних двух шагов, сервер может выбрать необходимого менеджера по идентификатору интерфейса и UUID объекта, указываемых в удаленном вызове.

(4) Серверное приложение сообщает подсистеме времени выполнения, какие транспортные протоколы можно будет использовать для удаленных вызов, и подсистема времени выполнения создает одну или несколько EP для каждого указанного протокола.

(5) Сервер может зарегистрировать информацию, представляющую собой запись вида идентификатор интерфейса / информация полного связывания / UUID объекта в карте EP. Таким образом, когда сервер получает вызов с информацией о частичном связывании (т.е. без указания EP), то он в состоянии, используя карту EP, выбрать EP, которая способна обработать вызов.

(6) Сервер может экспортировать информацию связывания в одну или несколько записей службы имен. Экспортируемая информация аналогична регистрируемой в карте EP на предыдущем шаге за исключением одного важного отличия. Информация связывания, экспортируемая в службу имен, не содержит сведений о EP, а содержит только данные о протоколах и адрес сервера (т.е. является информацией частичного связывания). Это сделано для того, чтобы служба имен содержала как можно более постоянную информацию связывания.

Замечание: Не все выше перечисленные шаги являются обязательными. Сервер может избежать импортирования информации связывания в карту EP и службу имен (шаги 5 и 6). В этом случае клиент должен будет обладать необходимой информацией и осуществлять связывание при помощи строки связывания (статическое связывание).

После того, как сервер выполнит указанные шаги, он будет готов обрабатывать удаленные вызовы, содержащие следующую информацию:

  • информация полного или частичного связывания;
  • идентификатор интерфейса;
  • UUID объекта;
  • номер операции.

Шаги связывания на стороне клиента

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

Рассмотрим подробно шаги связывания на стороне клиента.

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

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

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

Методы связывания

Существуют три метода связывания:

(1) Явное связывание.

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

(2) Неявное связывание.

При неявном связывании клиент определяет дескриптор связывания глобально для всего интерфейса. Stub клиента автоматически использует этот дескриптор при каждом вызове операции из этого интерфейса. При использовании этого метода клиент должен выполнить первый шаг связывания только один раз для каждого интерфейса.

(3) Автоматическое связывание.

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

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

Алгоритм маршрутизации удаленного вызова

Рассмотрим, каким образом происходит непосредственный вызов операции клиентом, когда вся необходимая для этого информация связывания уже известна (второй шаг связывания на стороне клиента).

Как уже отмечалось, во время вызова клиент может использовать информацию частичного или полного связывания. При применении информации частичного связывания ( EP клиенту не известна) EP определяется при помощи карты EP, расположенной на сервере, который выполняет удаленный вызов. Для этой цели стандартом DCE RPC для каждого протокола фиксируется некоторая EP, и через эти EP происходят запросы к карте EP. В карте EP осуществляется поиск EP, ассоциированной с требуемым идентификатором интерфейса и UUID объекта, если он указывается клиентом. Если при удаленном вызове UUID объекта не указывается, используется объект с UUID, зарегистрированным на сервере для применения по умолчанию.

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

Результатом выбора менеджера является то, что теперь сервер по номеру операции, указанному в запросе, и EPV менеджера может получить указатель на процедуру, реализующую данную операцию, и вызвать ее.

Функции RPC API

RPC API является программным интерфейсом для доступа к подсистеме времени выполнения. В заключение описания DCE RPC кратко рассмотрим функции RPC API.

(1) Функции связывания

Функции этой категории управляют связыванием клиента и сервера, дающим возможность удаленного вызова. Функции связывания можно разделить на две категории:

  • Функции установления клиент-серверного коммуникационного взаимодействия с использованием подходящего транспортного протокола;
  • Функции, устанавливающие взаимосвязь между элементами связывания внутри сервера.

(2) Функции взаимодействия со службой имен

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

(3) Функции работы с EP

Функции данной категории используются сервером для регистрации EP в карте EP.

(4) Функции защиты

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

(5) Функции управления памятью stub

Функции данной категории используются приложением для распределения памяти, необходимой для работы stub. Они обычно используются при удаленных вызовах процедур, параметры которых передаются по ссылкам.

(6) Функции управления

Сервер автоматически экспортирует набор операций, которые используются для удаленного управления этим сервером. RPC API функции управления используют эти операции.

(7) Функции работы с UUID

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

2. Механизм удаленного вызова процедур ONC RPC, разработанный корпорацией Sun Microsystems.


Перейдем к рассмотрению механизма удаленного вызова процедур, разработанного корпорацией Sun Microsystems, в рамках проекта Open Network Computing (ONC) [3,5,6].

В отличие от механизма DCE RPC, описанного в первой части, в механизме ONC RPC определяются только протоколы, используемые для осуществления удаленных вызовов. Методы же использования этих протоколов зависит от реализации.

Модель ONC RPC

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

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

Термины "клиент" и "сервер" является здесь условными, поскольку. сервер, предоставляющий некоторый сервис клиентам, сам может выступать в роли клиента некоторого другого сервера.

Теперь перейдем к рассмотрению модели удаленных вызовов ONC RPC в сравнении с локальными вызовами.

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

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

При такой модели удаленных вызовов только один из процессов (клиентский или серверный) активны в каждый момент времени. Но эта модель является примером, поскольку протокол ONC RPC не накладывает ограничений на реализацию параллелизма. Например, можно реализовать асинхронные вызовы, т.е. клиент может выполнять другую работу (в отдельном процессе) во время ожидания ответа от сервера. Аналогично, сервер может запускать новый процесс для выполнения каждого вызова. Таким образом, во время обработки предыдущих вызовов сервер может получать новые вызовы.

Перечислим наиболее важные аспекты отличия удаленных вызовов от локальных:

(1) Обработка ошибок

При использовании удаленных вызовов необходимо обрабатывать ошибки сети и те, которые возникают на удаленном сервере.

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

(3) Производительность

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

(4) Связывание

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

(5) Транспортный протокол

Транспортный протокол определяет, как сообщения пересылаются между клиентом и сервером. Протокол ONC RPC является транспортно-независимым, т.е. он может работать с любыми транспортными протоколами, поддерживаемыми операционной системой.

(6) Представление данных

При использовании удаленных вызовов в системах с разнородными архитектурами необходимо использовать стандартное представление данных. С этой целью используется протокол External Data Representation (XDR) [4]. Таким образом, для пересылки параметров и результатов между клиентом и сервером можно использовать разнообразные структуры данных, не задумываясь об их представлениях в различных архитектурах.

(7) Семантика вызова

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

(8) Аутентификация

Поскольку удаленные вызовы могут осуществляться в незащищенной сети, необходима аутентификация клиента на сервере [6]. Для этого каждое сообщение протокола ONC RPC содержит поля, необходимые для аутентификации клиента на сервере или сервера на клиенте. Механизм защиты и контроля доступа может быть реализован над протоколом ONC RPC. Таким образом, может поддерживаться несколько различных протоколов аутентификации. Информация об используемом протоколе аутентификации указывается в специальном поле каждого сообщения RPC.

Транспортные протоколы и семантика

Протокол ONC RPC реализуется над транспортными протоколами. Протокол ONC RPC не заботится о том, как сообщения пересылаются от клиента к серверу, а только формирует и интерпретирует сообщения. Тем не менее, при выборе транспортного протокола необходимо учитывать некоторые важные особенности. Например, транспортный протокол может накладывать ограничения на максимальный размер сообщения RPC, или это может быть протокол, ориентированный на установление соединения (например, TCP), где таких ограничений нет.

Важно отметить, что ONC RPC не пытается добиваться надежной пересылки сообщений RPC, т. е. приложение должно учитывать уровень надежности доставки, предоставляемый используемым транспортным протоколом. Если используется надежный транспортный протокол (такой, как TCP), то уровень надежности достаточно высок. Если использовать ненадежный транспортный протокол (такой, как UDP), то необходимо реализовывать собственный механизм повторной пересылки сообщения RPC после истечения времени ожидания ответа и выявления нежелательных повторных пересылок сообщений, так как протокол ONC RPC протокол не поддерживает такие механизмы.

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

Например, предположим, что протокол ONC RPC, базируется на ненадежном транспортном протоколе UDP. Если приложение после истечения времени ожидания ответа повторно посылает сообщение RPC, вызывающее процедуру, и снова не получает ответа, то невозможно ничего сказать о числе раз выполнения процедуры. Но если ответ получен, то можно сделать вывод, что процедура была запушена хотя бы один раз.

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

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

Связывание

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

Рекомендуемый механизм связывания описан в документе [5]. Обсудим его более подробно.

RPC-сервис определяется тройкой значений:

  • номер программы;
  • номер версии;
  • транспортный адрес.

Транспортный адрес, в свою очередь, состоит из сетевого адреса и транспортного селектора. Если, например, сервис доступен через протоколы TCP/IP или UDP/IP, то сетевым адресом является IP адрес, а транспортным селектором - номер порта TCP или UDP.

Таким образом, чтобы взаимодействовать с данным сервисом, клиенту необходимо знать номер программы, номер версии и транспортный адрес. Номер программы и номер версии обычно встраиваются в клиентскую программу, тогда как транспортный адрес определяется динамически (на стадии выполнения программы).

Теперь рассмотрим общую последовательность шагов связывания. Происходит это следующим образом.

На каждом сервере запускается поисковый сервис, который представляет собой программу с номером (100000). Номера версий этой программы могут быть равными 2, 3 или 4.

Для представления транспортного адреса в версиях 3 и 4 используется транспортно-независимый формат, называемый универсальным адресным форматом. Адрес в универсальном адресном формате представляется в виде строки ASCII, изображающей транспортно-зависимый адрес. Таким образом, эти версии могут быть использованы для клиента и сервера при работе с любым транспортом.

Версия 2 является устаревшей, она использовалась только для работы на транспортных протоколах TCP и UDP, поскольку работала с портами этих протоколов напрямую.

После того, как поисковый сервис запушен, он регистрируется на заранее известном транспортном селекторе каждого протокола (например, для протоколов TCP и UDP - это порт номер 111).

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

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

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

Заключение

В заключение проведем сравнительный анализ описанных в статье механизмов.

Стандарт DCE RPC является намного более общим, чем ONC RPC, поскольку в DCE RPC определяются не только протокол RPC и механизм связывания, но стандартизируются многие другие аспекты, которые в ONC RPC зависят от реализации:

  • API интерфейс доступа к подсистеме времени выполнения.
    Это в значительной степени увеличивает переносимость распределенных приложений.
  • Интеграция со службой имен.
    За счет этого можно легко и эффективно сделать широкодоступными операции, предоставляемые сервером.
  • Накладываются требования на реализацию сервера (параллелизм и удаленное управление).
    Это избавляет программиста от необходимости собственной реализации подобных операций и повышает эффективность работы сервера.
  • Язык описания интерфейса (IDL) и компилятор с него.
    За счет этого достигается полная прозрачность при использовании удаленных ресурсов и упрощается процесс разработки распределенных приложений.

Рассмотрим теперь отличия, относящиеся непосредственно к RPC протоколам и механизму связывания.

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

DCE RPC определяется несколько семантик выполнения удаленных вызовов, и при описании интерфейса, предоставляемого сервером, можно указать, какая семантика будет применяться при выполнении каждой операции. В ONC RPC нет такой определенности относительно семантики выполнения, и все в большей степени зависит от используемого транспортного протокола и даже от реализации подсистемы времени выполнения.

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

DCE RPC является обобщением всего накопленного на настоящее время опыта использования удаленных вызовов при построении распределенных систем.

Список литературы

  1. "X/Open DCE: Remote Procedure Call" Open Software Foundation (www.opengroup.org)
  2. Birrell, A. D. And Nelson, B. J., "Implementing Remote Procedure Calls", XEROX CSL-83-7, October 1983.
  3. "RPC: Remote Procedure Call Protocol Specification Version 2 " (draft-ietf-oncrpc-remote-03.txt на сервере www.ietf.org)
  4. "XDR: External Data Representation Standard " (RFC 1832 на сервере www.ietf.org)
  5. "Binding Protocols for ONC RPC Version 2" (RFC 1833 на сервере www.ietf.org)
  6. "Authentication Mechanisms for ONC RPC " (draft-ietf-oncrpc-auth-03.txt на сервере www.ietf.org)
Максим Гринев
Факультет ВМиК Московского государственного университета им. М.В. Ломоносова