Файл: Варианты архитектуры клиент-сервер.pdf

ВУЗ: Не указан

Категория: Курсовая работа

Дисциплина: Не указана

Добавлен: 03.07.2023

Просмотров: 457

Скачиваний: 3

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

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

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

Основное назначение промежуточного программного обеспечения заключается в обеспечении доступа приложения или пользователя к различным услугам, предоставляемым на серверах, причем так, чтобы не беспокоиться о различиях серверов. Стандартным средством доступа к реляционной базе данных как для локального, так и для удаленного пользователя или приложения является язык структурированных запросов (SQL). Однако многие производители реляционных баз данных, хотя и поддерживают язык SQL, добавили к нему свои собственные расширения. Это, с одной стороны, позволяет производителям различать свою продукцию, но, с другой стороны, приводит к несовместимости.[6]

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

На роль промежуточного программного обеспечения полезно взглянуть с точки зрения логики, а не реализации. Вся распределенная система может рассматриваться как набор приложений и ресурсов, доступных пользователю. Пользователям не нужно беспокоиться о расположении данных или приложений. Все приложения работают поверх унифицированного прикладного программного интерфейса (Application Programming Interface, API). [7]За маршрутизацию запросов клиента к соответствующему серверу отвечает промежуточное программное обеспечение, присутствующее на всех клиентских и серверных платформах.


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

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

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

Распределенную передачу сообщений, реализующую функциональность

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

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

Примитив Send используется процессом, желающим отправить сообщение. Входными параметрами этого примитива являются идентификатор получающего процесса и содержимое сообщения. Модуль передачи сообщений формирует блок данных, включающий эти два элемента. Этот блок данных посылается на машину, на которой работает получающий процесс, при помощи каких-либо сетевых протоколов, например, TCP/IP. Когда адресат получает блок данных, этот блок направляется модулю передачи сообщений. Этот модуль исследует поле идентификатора процесса и сохраняет сообщение в буфере этого процесса.

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


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

Надежная передача сообщений

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

Синхронные и асинхронные системы передачи сообщений

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

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


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

Уделенные вызовы процедур

Концепция вызова удаленных процедур (remote procedure call — RPC) была разработана и реализована в компанией XEROX еще начале 80-х годов XX века. Общий смысл RPC можно представить так: программа может выполнять не только собственные (скомпилированные) процедуры и функции, но и обращаться к процедурам удаленного сервера

Для установки связи, передачи вызова и возврата результата клиентский и серверный процессы обращаются к специальным компонентам – «заглушкам», соответственно клиентской и серверной (client stub и server stub). Эти stub'ы не реализуют никакой прикладной логики и предназначены только для организации взаимодействия удаленных (в общем случае) приложений. Все RPC-обращения клиента (имена функций и списки параметров) упаковываются клиентской заглушкой в сетевые сообщения (этот процесс называется marshaling) и ей же передаются серверной заглушке. Та, в свою очередь, распаковывает полученные данные (unmarshaling), передает их реальной функции сервера, а полученные результаты упаковывает в обратном порядке. Клиентская заглушка принимает ответ, распаковывает его и возвращает в приложение. Таким образом, процедуры-заглушки изолируют прикладные модули клиента и сервера от уровня сетевых коммуникаций.

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

У RPC как средства организации сетевого взаимодействия есть ряд минусов, кроющихся в самой парадигме структурного программирования:


Синхронные запросы — RPC приостанавливает выполнение приложения до тех пор, пока сервер не вернет требуемые данные.

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

Для устранения этих недостатков были разработаны более совершенные механизмы реализации RPC:

асинхронные RPC, позволяющие избежать приостановки выполнения клиентского приложения посредством функций обратного вызова (call-back functions);

код заглушек вынесен в динамически подключаемые библиотеки.

Протокол взаимодействия RPC также может повлиять на работу системы. Рассмотрим гипотетический фрагмент кода:

for (i = 0, i < 1000, i++)

for (j = 0, j < 1000, j++)

RPC_call();[8]

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

Привязка клиента и сервера

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

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

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