
- •Глава 2 Связь
- •2.1. Уровни протоколов
- •2.1. Уровни протоколов 83
- •84 Глава 2. Связь
- •2.1. Уровни протоколов 85
- •2.1.1. Низкоуровневые протоколы
- •86 Глава 2. Связь
- •2.1. Уровни протоколов 87
- •2.1.2. Транспортные протоколы (метод_Метелап лр_1)
- •88 Глава 2. Связь
- •2.1. Уровни протоколов 89
- •92 Глава 2. Связь
- •2.1.3. Протоколы верхнего уровня
- •2.1. Уровни протоколов 91
- •92 Глава 2. Связь
- •2.2. Удаленный вызов процедур 93
- •2.2. Удаленный вызов процедур
- •94 Глава 2. Связь
- •2.2.1. Базовые операции rpc
- •2.2. Удаленный вызов процедур 95
- •96 Глава 2. Связь
- •2.2. Удаленный вызов процедур 97
- •98 Глава 2. Связь
- •2.2.2. Передача параметров
- •2.2. Удаленный вызов процедур 99
- •100 Глава 2. Связь
- •2.2. Удаленный вызов процедур 101
- •102 Глава 2. Связь
- •2.2. Удаленный вызов процедур 103
- •2 .2.3. Расширенные модели rpc
- •104 Глава 2. Связь
- •2.2. Удаленный вызов процедур 105
- •106 Глава 2. Связь
- •2.2.4. Пример — dce rpc
- •2.2. Удаленный вызов процедур 107
- •108 Глава 2. Связь
- •2.2. Удаленный вызов процедур 109
- •110 Глава 2. Связь
- •2.3. Обращение к удаленным объектам 111
- •2.3. Обращение к удаленным объектам
- •112 Глава 2. Связь
- •2.3.1. Распределенные объекты
- •2.3. Обращение к удаленным объектам 113
- •114 Глава 2. Связь
- •2.3.2. Привязка клиента к объекту
- •2.3. Обращение к удаленным объектам 115
- •116 Глава 2. Связь
- •2.3. Обращение к удаленным объектам 117
- •2.3.3. Статическое и динамическое удаленное обращение к методам
- •118 Глава 2. Связь
- •2.3.4. Передача параметров
- •2.3. Обращение к удаленным объектам 119
- •120 Глава 2. Связь
- •2.3.5. Пример 1 — удаленные объекты dce
- •2.3. Обращение к удаленным объектам 121
- •122 Глава 2. Связь
- •2.3.6. Пример 2 — Java rmi
- •2.3. Обращение к удаленным объектам 123
- •124 Глава 2. Связь
- •2.3. Обращение к удаленным объектам 125
- •126 Глава 2. Связь
- •2.4. Связь посредством сообщений
- •2.4.1. Сохранность и синхронность во взаимодействиях
- •2 .4. Связь посредством сообщений 127
- •128 Глава 2. Связь
- •2.4. Связь посредством сообщений 129
- •130 Глава 2. Связь
- •2.4. Связь посредством сообщений 131
- •2.4.2. Нерезидентная связь на основе сообщений
- •132 Глава 2. Связь
- •2.4. Связь посредством сообщений 133
- •134 Глава 2. Связь
- •2.4. Связь посредством сообщений 135
- •136 Глава 2. Связь
- •2.4.3. Сохранная связь на основе сообщений
- •2.4. Связь посредством сообщений 137
- •1 38 Глава 2. Связь
- •2.4. Связь посредством сообщений 139
- •140 Глава 2. Связь
122 Глава 2. Связь
У распределенных объектов в DCE имеется одна проблема, связанная с их чрезвычайной близостью с RPC: не существует механизма прозрачных ссылок на объекты. Клиент имеет в лучшем случае дескриптор привязки (binding handle), ассоциированный с именованным объектом. Дескриптор привязки содержит идентификатор интерфейса, транспортный протокол, используемый для связи с сервером объектов, а также адрес и конечную точку хоста сервера. Дескриптор привязки может быть преобразован в строку и в таком виде передан другому процессу.
Отсутствие приемлемого механизма ссылок на объекты в пределах системы делает передачу параметров в DCE более сложной, чем в большинстве объектных систем. Разработчик приложений для RPC должен сам придумывать механизм передачи параметров. На деле это означает, что необходимо явно производить маршалинг объектов для передачи их по значению и самостоятельно создавать для этого соответствующие процедуры.
В качестве альтернативы разработчик может использовать делегирование. Для этого из спецификации интерфейса объекта генерируется специальная заглушка. Заглушка работает как оболочка нужного объекта и содержит только те методы, которые будут вызываться удаленными процессами. Заглушка может быть скомпонована с любым процессом, который хочет использовать этот объект. Преимущества такого подхода становятся понятны, если вспомнить, что DCE разрешает передавать удаленные ссылки на заглушки в качестве параметров вызовов RPC. Соответственно, появляется возможность ссылаться на объекты системы при помощи ссылок на заглушки.
Дополнительную информацию по объектному программированию в DCE можно найти в [335, 476].
2.3.6. Пример 2 — Java rmi
В DCE распределенные объекты были добавлены в качестве расширения вызовов удаленных процедур. Вместо того чтобы указывать удаленную процедуру на сервере, клиент указывал удаленную процедуру для объекта на сервере. Отсутствие подобающего механизма ссылок на объекты системы подчеркивало, что мы действительно имеем дело с простым расширением RPC.
Взглянем теперь на распределенные объекты с абсолютно другой точки зрения. В Java распределенные объекты интегрированы с языком. Основная цель этого — сохранить, насколько это возможно, семантику нераспределенных объектов. Другими словами, создатели языка Java стремились к высокому уровню прозрачности распределения. Однако, как мы увидим, создатели Java также решили, что в тех случаях, когда высокая степень прозрачности может быть неэффективна, затруднительна или нереализуема, распределенность может быть явной.
Модель распределенных объектов Java
Язык Java также поддерживает распределенные объекты исключительно в форме удаленных объектов. Напомним, что удаленный объект — это распределенный
2.3. Обращение к удаленным объектам 123
объект, тело которого постоянно находится на одной и той же машине, а интерфейсы доступны удаленным процессам. Интерфейсы реализованы обычным образом через заместителя, который предоставляет те же интерфейсы, что и удаленный объект. Сам заместитель имеет вид локального объекта, находящегося в адресном пространстве клиента.
Между удаленными и локальными объектами существует лишь несколько различий, но различия эти тонки и важны. Во-первых, значительно различается клонирование локальных и удаленных объектов. Клонирование локального объекта О приводит к появлению нового объекта такого же типа, что и О, в точно таком же состоянии. Процедура клонирования возвращает точную копию клонированного объекта. Подобная семантика слабо применима к удаленным объектам. Если мы попытаемся создать точную копию удаленного объекта, нам потребуется клонировать не только сам объект на его сервере, но и заместитель на каждом из клиентов, которые в этот момент привязаны к удаленному объекту. Поэтому операция клонирования удаленного объекта производится только на сервере. Она приводит к созданию точной копии объекта в адресном пространстве сервера. Заместитель объекта не клонируется. Если клиент на удаленной машине хочет получить доступ к клону объекта на сервере, он должен сначала выполнить повторную привязку к этому объекту.
Более существенное различие между локальными и удаленными объектами в Java заключается в семантике блокировки объектов. Java позволяет построить любой объект в виде монитора. Для этого достаточно объявить один из методов синхронизируемым (synchronized). Если два процесса одновременно вызовут синхронизируемый метод, работать будет только один из них, в то время как второй окажется заблокированным. Таким образом, мы можем гарантировать, что доступ к внутренним данным объекта будет осуществляться только последовательно. Как и в мониторе, процесс может быть заблокирован и изнутри объекта в ожидании выполнения некоторого условия, как мы описывали в главе 1.
Рассуждая логически, блокировка в удаленных объектах — дело несложное. Предположим, что клиент А вызвал синхронизируемый метод удаленного объекта. Чтобы получить доступ к удаленному объекту, который всегда выглядит так же, как локальный, необходимо блокировать А на уровне клиентской заглушки, которая реализует интерфейс объекта и к которой А имеет прямой доступ. Точно так же и другой клиент на другой машине должен быть блокирован до пересылки запроса на сервер. Это означает, что нам необходимо блокировать разных клиентов на различных машинах. Как мы увидим в главе 5, распределенная синхронизация может оказаться довольно сложным делом.
Альтернативный подход состоит в том, чтобы производить блокировку только на сервере. В принципе это неплохо работает, но возникают проблемы с нарушениями работы клиентов в момент обработки сервером их обращений. Как мы увидим в главе 7, обработка подобных ситуаций требует достаточно хитроумного протокола и способна значительно снизить общую производительность обращений к удаленным методам.
Поэтому разработчики Java RMI ограничили блокировку удаленных объектов блокировкой заместителей [494]. На практике это означает, что просто путем