
- •Глава 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. Связь
2.2. Удаленный вызов процедур 93
Т акой подход к подразделению на уровни приводит нас к слегка измененной эталонной модели взаимодействия (рис. 2.5). По сравнению с моделью OSI сеансовый уровень и уровень представления заменены одним промежуточным уровнем, который содержит не зависящие от приложений протоколы. Как мы говорили, эти протоколы нельзя поместить на более низкие уровни. Истинные транспортные службы также могут быть представлены в виде служб промежуточного уровня. Для этого не потребуется даже модификации. Этот подход аналогичен переносу UDP на транспортный уровень. Точно так же службы промежуточного уровня могут включать в себя службы пересылки сообщений, схожие с теми, которые предоставляются на транспортном уровне.
В оставшейся части этой главы мы сосредоточимся на четырех высокоуровневых коммуникационных службах промежуточного уровня: удаленном вызове процедур, удаленном обращении к объектам, очередям сообщений и потокам данных.
2.2. Удаленный вызов процедур
Основой множества распределенных систем является явный обмен сообщениями между процессами. Однако процедуры send и receive не скрывают взаимодействия, что необходимо для обеспечения прозрачности доступа. Эта проблема была известна давно, но по ней мало что было сделано до появления в 1980 году статьи [62], в которой предлагался абсолютно новый способ взаимодействия. Хотя идея была совершенно простой (естественно, после того как кто-то все придумал), ее реализация часто оказывается весьма хитроумной. В этом разделе мы рассмотрим саму концепцию, ее реализацию, сильные и слабые стороны.
Если не вдаваться в подробности, в упомянутой статье было предложено позволить программам вызывать процедуры, находящиеся на других машинах. Когда процесс, запущенный на машине А, вызывает процедуру с машины В, вызываю-
94 Глава 2. Связь
щ ий процесс на машине А приостанавливается, а выполнение вызванной процедуры происходит на машине В. Информация может быть передана от вызывающего процесса к вызываемой процедуре через параметры и возвращена процессу в виде результата выполнения процедуры. Программист абсолютно ничего не заметит. Этот метод известен под названием удаленный вызов процедур (Remote Procedure Call, RPC).
Базовая идея проста и элегантна, сложности возникают при реализации. Для начала, поскольку вызывающий процесс и вызываемая процедура находятся на разных машинах, они выполняются в различных адресных пространствах, что тут же рождает проблемы. Параметры и результаты также передаются от машины к машине, что может вызвать свои затруднения, особенно если машины не одинаковы. Наконец, обе машины могут сбоить, и любой возможный сбой вызовет разнообразные сложности. Однако с большинством из этих проблем можно справиться, и RPC является широко распространенной технологией, на которой базируются многие распределенные системы.
2.2.1. Базовые операции rpc
Мы начнем с обсуждения общепринятых вызовов процедур, а затем рассмотрим, как вызов может быть распределен между клиентской и серверной частями системы, каждая из которых выполняется на различных машинах.
Общепринятые вызовы процедур
Для того чтобы понять, как работает RPC, важно сначала разобраться, как осуществляются общепринятые (в пределах одной машины) вызовы процедур. Рассмотрим вызов в языке типа С:
count = read(fd, buf, bytes);
Здесь fd — целое, указывающее на файл; buf — массив символов, в который будут считываться данные; bytes — другое целое, говорящее, сколько байт следует считать. Если вызов производится из главной программы, стек до вызова выглядит так, как показано на рис. 2.6, а. Делая вызов, вызывающая программа помещает параметры в стек в порядке «последний первым», как показано на рис. 2.6, б. Причина, по которой компилятор С помещает параметры в стек в обратном порядке, заключается в функциях типа printf. Чтобы выполняться, функция printf всегда должна знать, где искать свой первый аргумент — строку формата. После завершения read система помещает возвращаемое значение в регистр, удаляет адрес возврата и возвращает управление назад, в вызвавшую программу. Затем вызвавшая программа удаляет из стека параметры, приводя его в исходное состояние.
Следует особо отметить некоторые моменты. Во-первых, в С параметры могут передаваться как по значению, так и по ссылке. Параметр-значение, такой как fd или bytes, просто копируется в стек, что и показано на рис. 2.6, б. Для вызываемой процедуры параметр-значение представляет собой просто инициализированную локальную переменную. Вызываемая процедура может ее изменить,