Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Сеансовые протоколы и протоколы представления↑ Стр 1 из 10Следующая ⇒ Содержание книги
Похожие статьи вашей тематики
Поиск на нашем сайте Глава 2 Связь 2.1.Уровни протоколов 2.2.Удаленный вызов процедур 2.3.Обращение к удаленным объектам 2.4.Связь посредством сообщений 2.5.Связь на основе потоков данных 2.6.Итоги Связь между процессами — это суть распределенных систем. Нет смысла изучать распределенные системы, не рассматривая при этом во всех подробностях способы обмена информацией между различными процессами, выполняющимися на разных машинах. Взаимодействие в распределенных системах всегда базируется на низкоуровневом механизме передачи сообщений, предоставляемом базовой сетью. Как мы обсуждали в предыдущей главе, реализация взаимодействия через передачу сообщений сложнее, чем использование примитивов на базе разделяемой памяти. Современные распределенные системы часто включают в себя тысячи или даже миллионы процессов, разбросанных по ненадежной сети, такой как Интернет. Если не заменить простейшие средства взаимодействия в компьютерных сетях чем-то иным, разработка масштабных приложений будет достаточно сложной. Мы начнем эту главу с обсуждения правил, которых придерживаются сообщающиеся между собой процессы. Их обычно называют протоколами. Мы сосредоточимся на структурировании этих протоколов в виде уровней. Затем мы рассмотрим четыре широко распространенные модели взаимодействия: 1. удаленный вызов процедур (Remote Procedure Call, RPC), 2. удаленное обращение к методам (Remote Method Invocation, RMI), 3. ориентированный на сообщения промежуточный уровень (Message-Oriented Middleware, MOM) ) и 4. потоки данных (streams). Нашей первой моделью взаимодействия в распределенных системах станет удаленный вызов процедур. Механизм RPC нацелен на сокрытие большей части проблем передачи сообщений и идеален для приложений архитектуры клиент-сервер. Усовершенствованный вариант модели RPC имеет вид удаленного обра-
82 Глава 2. Связь щения к методам, которое основано на представлении распределенных объектов. Механизмы RPC и RMI рассматриваются в отдельных разделах. Во многих распределенных приложениях связь не ограничивается слегка урезанным шаблоном взаимодействий клиента и сервера. В подобных случаях мыслить категориями сообщений оказывается предпочтительнее. Однако применение разнообразных низкоуровневых средств связи компьютерных сетей приведет к серьезным нарушениям прозрачности распределения. Альтернативой им является высокоуровневая модель очереди сообщений, связь в которой очень напоминает системы электронной почты. Ориентированный на сообщения средний уровень — это достаточно важная тема, чтобы отвести отдельный раздел и на нее. Что касается мультимедиа в распределенных системах, понемногу становится очевидным, что таким системам недостает поддержки передачи непрерывных потоков, таких как аудио или видео. Им необходимо понятие потока, который позволяет поддерживать непрерывно идущие сообщения в соответствии с различными ограничениями по синхронизации. Потоки обсуждаются в последнем разделе этой главы. Уровни протоколов В условиях отсутствия совместно используемой памяти вся связь в распределенных системах основана на обмене (низкоуровневыми) сообщениями. Если процесс А хочет пообщаться с процессом В, он должен сначала построить сообщение в своем собственном адресном пространстве. Затем он выполняет системный вызов, который пересылает сообщение по сети процессу В. Хотя основная идея выглядит несложной, во избежание хаоса А и В должны договориться о смысле пересылаемых нулей и единиц. Если А посылает потрясающий новый роман, написанный по-французски, в кодировке IBM EBCDIC, а В ожидает результаты переучета в супермаркете, на английском языке и в кодировке ASCII, их взаимодействие будет не слишком успешным. Необходимо множество различных договоренностей. Сколько вольт следует использовать для передачи нуля, а сколько для передачи единицы? Как получатель узнает, что этот бит сообщения — последний? Как ему определить, что сообщение было повреждено или утеряно, и что ему делать в этом случае? Какую длину имеют числа, строки и другие элементы данных и как они отображаются? Короче говоря, необходимы соглашения различного уровня, от низкоуровневых подробностей передачи битов до высокоуровневых деталей отображения информации. Чтобы упростить работу с множеством уровней и понятий, используемых в передаче данных, Международная организация по стандартам (International Standards Organization, ISO) разработала эталонную модель, которая ясно определяет различные уровни, дает им стандартные имена и указывает, какой уровень за что отвечает. Эта модель получила название Эталонной модели взаимодействия открытых систем (Open Systems Interconnection Reference Model) [120].
2.1. Уровни протоколов 83 Это название обычно заменяется сокращением модель ISO OSI, или просто модель OSI. Следует заметить, что протоколы, которые должны были реализовы-вать части модели OSI, никогда не получали широкого распространения. Однако сама по себе базовая модель оказалась вполне пригодной для исследования компьютерных сетей. Несмотря на то что мы не собираемся приводить здесь полное описание этой модели и всех ее дополнений, небольшое введение в нее будет нам полезно. Дополнительные детали можно почерпнуть в [446]. Модель OSI разрабатывалась для того, чтобы предоставить открытым системам возможность взаимодействовать друг с другом. Открытая система — это система, которая способна взаимодействовать с любой другой открытой системой по стандартным правилам, определяющим формат, содержимое и смысл отправляемых и принимаемых сообщений. Эти правила зафиксированы в том, что называется протоколами {protocols). Для того чтобы группа компьютеров могла поддерживать связь по сети, они должны договориться об используемых протоколах. Все протоколы делятся на два основных типа. В протоколах с установлением соединения {connection-oriented) перед началом обмена данными отправитель и получатель должны установить соединение и, возможно, договориться о том, какой протокол они будут использовать. После завершения обмена они должны разорвать соединение. Системой с установлением соединения является, например, телефон. В случае протоколов без установления соединения {connectionless) никакой подготовки не нужно. Отправитель посылает первое сообщение, как только он готов это сделать. Письмо, опущенное в почтовый ящик, — пример связи без установления соединения. В компьютерных технологиях широко применяется как связь с установлением соединения, так и связь без установления соединения. В модели OSI взаимодействие подразделяется на семь уровней, как показано на рис. 2.1. Каждый уровень отвечает за один специфический аспект взаимодействия. Таким образом, проблема может быть разделена на поддающиеся решению части, каждая из которых может разбираться независимо от других. Каждый из уровней предоставляет интерфейс для работы с вышестоящим уровнем. Интерфейс состоит из набора операций, которые совместно определяют интерфейс, предоставляемый уровнем тем, кто им пользуется. Когда процесс А на машине 1 хочет пообщаться с процессом В на машине 2, он строит сообщение и посылает его прикладному уровню своей машины. Этот уровень может представлять собой, например, библиотечную процедуру или реа-лизовываться как-то иначе (например, внутри операционной системы или внешнего сетевого процессора). Программное обеспечение прикладного уровня добавляет в начало сообщения свой заголовок {header) и передает получившееся сообщение через интерфейс с уровня 7 на уровень 6, уровень представления. Уровень представления, в свою очередь, добавляет в начало сообщения свой заголовок и передает результат вниз, на сеансовый уровень и т. д. Некоторые уровни добавляют не только заголовок в начало, но и завершение в конец. Когда сообщение дойдет до физического уровня, он осуществит его реальную передачу, как это показано на рис. 2.2.
84 Глава 2. Связь
Когда сообщение приходит на машину 2, оно передается наверх, при этом на каждом уровне считывается и проверяется соответствующий заголовок. В конце концов сообщение достигает получателя, процесса В, который может ответить на него, при этом вся история повторяется в обратном направлении. Информация из заголовка уровня п используется протоколом уровня п. В качестве примера важности многоуровневых протоколов рассмотрим обмен информацией между двумя компаниями, авиакомпанией Zippy Airlines и поставщиком продуктов Mushy Meals, Inc. Каждый месяц начальник отдела обслуживания пассажиров Zippy просит свою секретаршу связаться с секретаршей менеджера по продажам Mushy и заказать 100 000 коробок «резиновых» цыплят. Обычно заказы пересылались почтой. Однако из-за постепенного ухудшения качества почтовых услуг в один прекрасный момент секретарши решают больше не писать друг другу письма, а связываться по факсу. Они могут делать это, не беспокоя своих боссов, поскольку протокол касается физической передачи заказов, а не их содержания.
2.1. Уровни протоколов 85 Точно так же начальник отдела обслуживания пассажиров может решить отказаться от цыплят и перейти на новый деликатес от Mushy, превосходные козьи ребра, это решение никак не скажется на работе секретарш. Это происходит потому, что у нас есть два уровня — боссы и их секретарши. Каждый уровень имеет:вой собственный протокол (темы для обсуждения и технологию), который можно изменить независимо от другого. Эта независимость делает многоуровневые протоколы привлекательными. Каждый уровень при появлении новых технологий может быть изменен независимо от других. В модели OSI, как было показано на рис. 2.1, не два уровня, а семь. Набор протоколов, используемых в конкретной системе, называется комплектом, или стеком протоколов. Важно отличать эталонную модель от реальных протоколов. Как мы отмечали, протоколы OSI никогда не были популярны. В противоположность им протоколы, разрабатывавшиеся для Интернета, такие как TCP и IP, используются повсеместно. В последующих пунктах мы кратко рассмотрим каж-лый из уровней модели OSI, начиная с нижнего. Однако вместо того, чтобы приводить примеры соответствующих протоколов OSI, мы рассмотрим протоколы 11нтернета, используемые на каждом из этих уровней. Низкоуровневые протоколы Мы начнем с обсуждения трех нижних уровней комплекта протоколов OSI. Эти три уровня совместно реализуют основные функции компьютерной сети. Физический уровень Физический уровень ответственен за передачу нулей и единиц. Сколько вольт использовать для передачи нуля или единицы, сколько бит в секунду можно передать и можно ли осуществлять передачу одновременно в двух направлениях — вот основные проблемы физического уровня. Кроме того, к физическому уровню относится размер и форма сетевых коннекторов (разъемов), а также число выводов и назначение каждого из них. Протоколы физического уровня отвечают за стандартизацию электрических, механических и сигнальных интерфейсов, чтобы, если одна машина посылает ноль, другая приняла его как ноль, а не как единицу. Было разработано множество стандартов физического уровня для различных носителей, например стандарт RS-232-C для последовательных линий связи. Канальный уровень Физический уровень только пересылает биты. Пока нет ошибок, все хорошо. Однако в реальных сетях происходят ошибки, и их нужно как-то находить и исправлять. Это и является главной задачей канального уровня. Он группирует биты в модули, обычно называемые кадрами {frames), и следит за тем, чтобы каждый кадр был передан правильно. Канальный уровень делает это путем помещения специальной битовой маски в начало и конец каждого кадра для их маркировки, а также путем вычисления контрольной суммы {checksum), то есть суммирования всех байтов кадра опреде-
86 Глава 2. Связь ленным образом. Канальный уровень добавляет контрольную сумму к кадру. Когда кадр принимается, приемник повторно вычисляет контрольную сумму данных и сравнивает результат с контрольной суммой, пришедшей вместе с кадром. Если они совпадают, кадр считается верным и принимается. Если они различны, получатель просит отправителя снова отправить этот кадр. Кадры последовательно нумеруются с указанием номеров в заголовке, так что все понимают, где какой кадр. На рис. 2.3 мы видим случай (отчасти патологический) посылки двух сообщений 1 и 2 с машины А на машину В. Сообщение с данными 0 посылается с машины А в момент времени 0. Когда в момент времени 1 это сообщение достигает машины В, обнаруживается, что оно повреждено помехами в линии передачи и контрольная сумма не соответствует действительности. Машина В обнаруживает это и в момент времени 2 запрашивает повторную посылку, отправляя соответствующее контрольное сообщение 0. К сожалению, в тот же самый момент машина А посылает сообщение 1. В ответ на полученный машиной А запрос на повторную посылку отправляется сообщение 0. Когда машина В получает сообщение с данными 1 (а ведь она запрашивала сообщение с данными 0!), она посылает машине А новое контрольное сообщение 1, настаивая на том, что она хочет получить сообщение с данными 0, а не 1. Когда контрольное сообщение 1 доходит до машины А, та посылает сообщение с данными 0 в третий раз. Задача этого обсуждения — не показать, насколько хорош описанный протокол (он очень плох), а объяснить, что на каждом уровне существует необходимость во взаимодействии между отправителем и получателем. Типичные сообщения: «Пошли, пожалуйста, сообщение п заново» — «Уже посылал дважды» —
2.1. Уровни протоколов 87 «Нет, ты этого не делал» — «А я говорю, делал» — «Ну ладно, пускай делал, все равно пошли еще раз» и т. д. Это взаимодействие происходит в полях заголовка, где определены различные запросы и ответы и могут поддерживаться параметры (например, номера кадров). Сетевой уровень В локальных сетях у отправителя обычно нет необходимости находить местоположение получателя. Он просто бросает сообщение в локальную сеть, а получа-тель забирает его оттуда. Глобальные сети, однако, содержат множество машин, каждая из которых имеет собственные линии связи с другими машинами. Так на крупномасштабной карте показано множество городов и соединяющих их дорог. Сообщение, посылаемое от отправителя к получателю, должно пройти массу сетевых сегментов, на каждом из которых происходит выбор исходящей линии. Задача выбора наилучшего пути называется маршрутизацией (routing) и является основной задачей сетевого уровня. Проблема усложняется тем, что наиболее короткий путь не всегда является наилучшим. На самом деле важна величина задержки на выбранном маршруте. ма. в свою очередь, зависит от объема трафика и числа сообщений, стоящих в очереди на отправку по различным линиям. С течением времени задержка мо же т меняться. Некоторые алгоритмы маршрутизации могут подстраиваться под •\:енения загруженности линий, некоторые же удовлетворяются тем, что при- нимают решение на основе усредненных значений.В настоящее время, вероятно, наиболее широко распространенным сетевым протоколом является не требующий установки соединения протокол Интерне- (Internet protocol, IP), входящий в комплект протоколов Интернета. На сете- вом уровне сообщение именуется термином пакет (packet). IP-пакет может быть послан без какой-либо предварительной подготовки. Маршрут каждого из 1Р-па- кетов до места назначения выбирается независимо от других пакетов. Никакие внутренние пути не выбираются заранее и не запоминаются. Протоколом с соединением, приобретающим популярность в настоящее вре-мя является виртуальный канал (virtual channel) па базе сетей ATM. Виртуальный канал в ATM — это непрямое соединение, устанавливаемое от источника к приемнику, возможно, проходящее через несколько промежуточных АТМ-комутаторов. Чтобы между двумя компьютерами не устанавливать каждый из виртуальных каналов по отдельности, набор виртуальных каналов может быть сгрупирован в виртуальный путь (virtual path). Виртуальный путь сравним с предопределенным маршрутом между двумя узлами, вдоль которого выстраиваются его виртуальные каналы. Изменение маршрута виртуального пути означает юматическую перекладку всех ассоциированных с ним каналов [194]. 2.1.2. Транспортные протоколы (метод_Метелап ЛР_1) ;нспортный уровень — это последняя часть того, что называют базовым стеком евых протоколов, поскольку в нем реализованы все службы, которые необхо- димы для построения сетевых приложений и которые не вошли в интерфейс се-
88 Глава 2. Связь тевого уровня. Другими словами, транспортный уровень дает возможность разработчикам приложений использовать базовую сеть, лежащую в его основе. Функции транспортного уровня На пути от отправителя к получателю пакеты могут теряться. В то время как одни приложения задействуют собственные процедуры исправления ошибок, другие предпочитают падежную связь. Предоставить им эту службу — дело транспортного уровня. Идея состоит в том, что приложение должно быть в состоянии передать сообщение транспортному уровню и ожидать того, что оно будет доставлено без потерь. После получения сообщения с прикладного уровня транспортный уровень разбивает его для успешной передачи на достаточно мелкие части, присваивает им последовательные номера и пересылает их. Взаимодействие на уровне заголовка транспортного уровня сводится к обсуждению того, какой пакет был послан, какой — принят, сколько места есть у адресата для приема дальнейших сообщений, что следует послать повторно и тому подобным вопросам. Надежное транспортное соединение (которое по определению представляет собой связь с установкой соединения) можно построить поверх сетевых служб как с соединениями, так и без соединений. В первом случае все пакеты будут доставлены в правильной последовательности (если они посылаются одновременно), а в последнем возможно, что один из пакетов пойдет по другому маршруту и придет раньше, чем пакет, посланный до него. Это побуждает программное обеспечение транспортного уровня складывать пакеты в правильной последовательности, чтобы поддержать представление о транспортном соединении как о большой трубе — вы кладете в него сообщения на одном конце, и они добираются до другого неповрежденными, в том же порядке, в котором и отправлялись. Транспортный протокол для Интернета называется протоколом управления передачей (Transmission Control Protocol, TCP). Он детально разобран в книге [109]. Комбинация TCP/IP в настоящее время является стандартом де-факто при сетевых взаимодействиях. Комплект протоколов Интернета также включает в себя не требующий соединения транспортный протокол под названием UDP (Universal Datagram Protocol — универсальный протокол датагралш), который, по сути, представляет собой IP с некоторыми небольшими дополнениями. Пользовательские программы, не нуждающиеся в протоколе с соединениями, обычно используют UDP. Официальный транспортный протокол ISO имеет пять разновидностей — от ТР0 до ТР4. Различия относятся к обработке ошибок и к возможности работать с несколькими транспортными соединениями на базе одного соединения низкого уровня (особенно Х.25). Выбор того, какой из них использовать, зависит от свойств лежащего ниже сетевого уровня. Никогда ни один из них не должен перегружаться. Время от времени предлагаются дополнительные транспортные протоколы. Так, например, для поддержки передачи данных в реальном времени был определен транспортный протокол реального времени (Real-time Transport Protocol, RTP). RTP — это кадровый протокол, который определяет формат пакета для
2.1. Уровни протоколов 89 данных реального времени, ничего не говоря о механизмах гарантированной доставки этих данных. Кроме того, в нем определен протокол для мониторинга и управления передачей RTP-пакетов [406]. TCP в архитектуре клиент-сервер Взаимодействие клиент-сервер в распределенных системах часто осуществляется путем использования транспортного протокола базовой сети. С ростом популярности Интернета нередко можно наблюдать построение приложений клиент-сервер и систем на базе TCP. Преимущества протокола TCP по сравнению с UDP состоят в том, что он надежно работает в любой сети. Очевидная оборотная сторона — протокол TCP создает значительную дополнительную нагрузку на сеть, особенно в тех случаях, когда базовая сеть высоконадежна, например, в локальных сетях. Когда на карту поставлены производительность и надежность, альтернативой всегда является протокол UDP в сочетании с дополнительными процедурами контроля ошибок и потоков, оптимизированными для конкретного приложения. Оборотная сторона этого подхода состоит в том, что приходится проделывать массу дополнительной работы, а также в том, что полученное решение будет частным, снижающим открытость системы. Протокол TCP во многих случаях непривлекателен из-за невозможности приспособить его для поддержки синхронного поведения запрос-ответ, используемого во многих взаимодействиях клиент-сервер. На рис. 2.4, а показано применение протокола TCP для поддержки взаимодействия клиент-сервер в нормальных условиях (когда сообщения не пропадают). Сначала клиент инициирует установление соединения, которое происходит по трехэтапному протоколу установления связи (первые три сообщения на рисунке). Этот протокол необходим для достижения договоренности о порядке нумерации пакетов, пересылаемых через соединение (детали можно найти в [446]). Когда соединение установлено, клиент посылает свой запрос (сообщение 4), сопровождаемый пакетом, требующим от сервера разорвать соединение (сообщение 5). Сервер отвечает немедленным подтверждением приема запроса от клиента, которое скомпоновано с подтверждением разрыва соединения (сообщение 6). Затем сервер выполняет требуемую работу и посылает клиенту ответ (сообщение 7), также сопровождаемый требованием разорвать соединение (сообщение 8). Клиент должен только послать подтверждение разрыва связи на сервер (сообщение 9). Ясно, что большая часть дополнительной нагрузки на сеть связана с управлением соединением. При использовании TCP для управления взаимодействием клиент-сервер гораздо дешевле будет скомбинировать установление соединения с немедленной посылкой запроса, а посылку ответа — с разрывом соединения. Получившийся протокол носит название TCP для транзакций (TCP for Transactions), сокращаемое до Т/ТСР. То, как функционирует этот протокол в нормальных условиях, можно увидеть на рис. 2.4, б. В нормальной обстановке происходит следующее: клиент посылает одно сообщение (сообщение 1), содержащее три порции информации: запрос на уста-
92 Глава 2. Связь новление соединения, собственно запрос к серверу и запрос, сообщающий серверу, что после этого он может немедленно разорвать соединение. Сервер отвечает только после того, как обработает запрос. Он может послать данные, для передачи которых и создавалось соединение, и немедленно потребовать его разрыва, что иллюстрирует сообщение 2. После этого клиенту остается только подтвердить разрыв соединения (сообщение 3). Протокол Т/ТСР, созданный как расширение TCP, автоматически преобразуется в нормальный протокол TCP, если другая сторона не поддерживает это расширение. Дополнительную информацию по TCP/IP можно найти в [437]. Протоколы верхнего уровня Поверх транспортного уровня OSI указывает на наличие трех дополнительных уровней. На практике используется только прикладной уровень. На самом деле в комплекте протоколов Интернета все, что находится выше транспортного уровня, собирается в одну «кучу». В этом пункте мы увидим, почему с точки зрения систем промежуточного уровня нас не устраивает ни подход OSI, ни подход Интернета. Прикладные протоколы Прикладной уровень модели OSI изначально должен был содержать набор стандартных сетевых приложений, например для работы с электронной почтой, передачи файлов и эмуляции терминала. В настоящее время он стал местом собрания всех приложений и протоколов, которые не удалось пристроить ни на один из более низких уровней. В свете эталонной модели OSI все распределенные системы являются просто приложениями. Чего в этой модели нет — так это четкого разграничения приложений, специальных протоколов приложений и протоколов общего назначения. Так, например, популярный в Интернете протокол передачи файлов (File Transfer Protocol, FTP) [203, 361] определяет передачу файлов между клиентской машиной и сервером. Этот протокол не следует путать с программой ftp, которая представляет собой законченное приложение для передачи файлов и совпадает (но не полностью) с реализацией протокола FTP для Интернета. Другим примером сугубо специального прикладного протокола [142] может служить протокол передачи гипертекста (Hypertext Transfer Protocol, HTTP), разработанный для удаленного управления и загрузки web-страниц. Протокол реализован в таких приложениях, как web-браузеры и web-серверы. Однако сейчас этот протокол используется и в системах, связь которых с Web не предполагается. Так, например, в RMI в языке Java протокол HTTP используется для обращения к удаленному объекту, защищенному брандмауэром [441]. Кроме того, существует множество протоколов общего назначения, используемых в различных приложениях. Они попали в прикладные протоколы, потому что их нельзя было отнести к транспортным. Во многих случаях они могут считаться протоколами промежуточного уровня, которые мы сейчас рассмотрим. Удаленный вызов процедур Основой множества распределенных систем является явный обмен сообщениями между процессами. Однако процедуры send и receive не скрывают взаимодействия, что необходимо для обеспечения прозрачности доступа. Эта проблема была известна давно, но по ней мало что было сделано до появления в 1980 году статьи [62], в которой предлагался абсолютно новый способ взаимодействия. Хотя идея была совершенно простой (естественно, после того как кто-то все придумал), ее реализация часто оказывается весьма хитроумной. В этом разделе мы рассмотрим саму концепцию, ее реализацию, сильные и слабые стороны. Если не вдаваться в подробности, в упомянутой статье было предложено позволить программам вызывать процедуры, находящиеся на других машинах. Когда процесс, запущенный на машине А, вызывает процедуру с машины В, вызываю-
94 Глава 2. Связь щий процесс на машине А приостанавливается, а выполнение вызванной процедуры происходит на машине В. Информация может быть передана от вызывающего процесса к вызываемой процедуре через параметры и возвращена процессу в виде результата выполнения процедуры. Программист абсолютно ничего не заметит. Этот метод известен под названием удаленный вызов процедур (Remote Procedure Call, RPC). Базовая идея проста и элегантна, сложности возникают при реализации. Для начала, поскольку вызывающий процесс и вызываемая процедура находятся на разных машинах, они выполняются в различных адресных пространствах, что тут же рождает проблемы. Параметры и результаты также передаются от машины к машине, что может вызвать свои затруднения, особенно если машины не одинаковы. Наконец, обе машины могут сбоить, и любой возможный сбой вызовет разнообразные сложности. Однако с большинством из этих проблем можно справиться, и RPC является широко распространенной технологией, на которой базируются многие распределенные системы. Базовые операции RPC Мы начнем с обсуждения общепринятых вызовов процедур, а затем рассмотрим, как вызов может быть распределен между клиентской и серверной частями системы, каждая из которых выполняется на различных машинах. Общепринятые вызовы процедур Для того чтобы понять, как работает RPC, важно сначала разобраться, как осуществляются общепринятые (в пределах одной машины) вызовы процедур. Рассмотрим вызов в языке типа С: count = read(fd, buf, bytes); Здесь fd — целое, указывающее на файл; buf — массив символов, в который будут считываться данные; bytes — другое целое, говорящее, сколько байт следует считать. Если вызов производится из главной программы, стек до вызова выглядит так, как показано на рис. 2.6, а. Делая вызов, вызывающая программа помещает параметры в стек в порядке «последний первым», как показано на рис. 2.6, б. Причина, по которой компилятор С помещает параметры в стек в обратном порядке, заключается в функциях типа printf. Чтобы выполняться, функция printf всегда должна знать, где искать свой первый аргумент — строку формата. После завершения read система помещает возвращаемое значение в регистр, удаляет адрес возврата и возвращает управление назад, в вызвавшую программу. Затем вызвавшая программа удаляет из стека параметры, приводя его в исходное состояние. Следует особо отметить некоторые моменты. Во-первых, в С параметры могут передаваться как по значению, так и по ссылке. Параметр-значение, такой как fd или bytes, просто копируется в стек, что и показано на рис. 2.6, б. Для вызываемой процедуры параметр-значение представляет собой просто инициализированную локальную переменную. Вызываемая процедура может ее изменить,
Параметр-ссылка в С — это указатель на переменную (то есть адрес переменной), а не ее значение. В вызове read второй параметр является параметром-ссылкой, поскольку массивы в С всегда передаются через ссылку. В стек на самом деле будет помещен адрес символьного массива. Если вызванная процедура использует этот параметр для помещения чего-либо в символьный массив, это приведет к изменению массива в вызывающей программе. Мы увидим, что разница между параметрами-значениями и параметрами-ссылками крайне важна для RPC. Существует еще один механизм передачи параметров, не применяющийся в С. Он называется вызов через копирование/восстановление {call-by-copy/restore). В этом случае до вызова вызывающей программой производится копирование переменной в стек, как при вызове по значению, а после завершения вызова — копирование этой переменной из стека назад, с удалением исходного значения этой переменной. В большинстве случаев это дает тот же эффект, что и при вызове по ссылке. Однако иногда, например, если один и тот же параметр присутствует в списке аргументов многократно, их семантика различается. Во многих языках вызов через копирование/восстановление отсутствует. Решение об использовании того или иного механизма передачи параметров принимается обычно разработчиками языка и является его фиксированным свойством. Раньше это решение зависело от типов передаваемых данных. В С, например, как мы видели, целые и другие скалярные типы всегда передаются по значению, а массивы — по ссылке. Некоторые компиляторы языка Ада поддерживают вызов через копирование/восстановление для изменяемых {in out) параметров, передавая остальные по ссылке. Определение языка позволяет выбрать любой вариант, который хоть немного упрощает семантику.
96 Глава 2. Связь Заглушки для клиента и сервера Идея, стоящая за RPC, состоит в том, чтобы удаленный вызов процедур выглядел точно так же, как и локальный. Другими словами, мы ждем от RPC прозрачности — вызывающая процедура не должна уведомляться о том, что вызываемая процедура выполняется на другой машине, и наоборот. Предположим, программа хочет считать некоторые данные из файла. Для чтения из файла необходимых данных программист помещает в код вызов read. В традиционной (однопроцессорной) системе процедура read извлекается компоновщиком из библиотеки и вставляется в объектный код программы. Это короткая процедура, которая обычно реализуется путем системного вызова read. Другими словами, процедура read — это интерфейс между кодом пользователя и локальной операционной системой. Даже если read — это системный вызов, он производится аналогичным образом, путем помещения параметров в стек, как показано на рис. 2.6, б. Таким образом, программист так и не узнает, что read делает что-то хитрое. RPC организует свою прозрачность аналогичным образом. Если read является удаленной процедурой (то есть будет исполняться на машине файлового сервера), в библиотеку помещается специальная версия read, называемая клиентской заглушкой {client stub). Как и оригинальная функция, она также вызывается в соответствии с последовательностью, показанной на рис 2.6, б. Как и оригинал, она также производит вызов локальной операционной системы, только в отличие от оригинальной функции клиентская заглушка ие запрашивает данные у операционной системы. Вместо этого она упаковывает параметры в сообщение и путем вызова процедуры send требует переслать это сообщение на сервер, как показано на рис. 2.7. После вызова процедуры send клиентская заглушка вызывает процедуру recei ve, блокируясь до получения ответа. Когда сообщение приходит на сервер, операционная система сервера передает его серверной заглушке {server stub). Серверная заглушка эквивалентна клиентской, но работает на стороне сервера. Это фрагмент кода, который преобразует приходящие по сети запросы в вызовы локальных процедур. Обычно серверная заглушка запускает процедуру recei ve и блокируется, ожидая входящих сообщений. После получения сообщения серверная заглушка распаковывает его, извлекая параметры, и традиционным способом (то есть так, как показано на рис. 2.6)
2.2. Удаленный вызов процедур 97 вызывает процедуру сервера. С точки зрения сервера это воспринимается как прямой вызов с клиента — параметры и адрес возврата находятся в стеке, где они и должны находиться, и ничего необычного в этом нет. Сервер делает свое дело и обычным порядком возвращает результат вызвавшей процедуре. Так, например, в случае чтения файла сервер заполняет данными буфер, на который указывает второй параметр. Этот буфер — внутренний буфер серверной заглушки. Когда серверная заглушка после окончания обработки вызова возвращает управление вызвавшей программе, она запаковывает результаты выполнения (буфер) в сообщение и вызывает процедуру send, чтобы возвратить их клиенту. После этого серверная заглушка вновь вызывает процедуру receive, переходя в режим ожидания следующего сообщения. Когда на клиентскую машину приходит ответное сообщение, операционная система клиента обнаруживает, что оно адресовано клиентскому процессу (на самом деле клиентской заглушке, но операционная система их не различает). Сообщение копируется в буфер ожидания, и клиентский процесс разблокируется. Клиентская заглушка рассматривает сообщение, распаковывает его, извлекая результаты, копирует их в память вызвавшей программы и, завершая работу, передае
|
||||||||
Последнее изменение этой страницы: 2016-09-19; просмотров: 631; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.222.44.156 (0.019 с.) |