Глава 10 Технологии сетевого взаимодействия корпоративных систем

Рассмотрим эволюцию технологий сетевого взаимодействия распределенных приложений и построение такого рода приложений. Одной из наиболее ранних технологий является удаленный вызов процедур – Remote Procedure Call. Во многом эта технология реализуется в Remoting при маршеринге, который будет рассмотрен несколько позднее. Еще одним подходом была передача сообщений, т. е. взаимодействие между распределенным приложением, между объектами. В одном из первых вариантов она называлась DCE – Distributed Computing Environment. Если рассматривать взаимодействие клиента и сервера, концепция открытых систем предполагает явное распределение ролей на клиент и сервер. При этом клиент – это компьютер, который осуществляет преимущественно запрос информации, в данном случае это вызов функции, которая на самом деле обращается к серверу, хотя это очевидно только из ее названия. Сервер осуществляет поиск, получение и предоставление отчетной информации для клиента в соответствии с его запросом. Кроме того, вспоминая главу об архитектуре, заметим, что помимо двух слоев клиент-серверной архитектуры (клиента и сервера), существует еще промежуточный слой, который предназначен для локализации взаимодействия. Но пока рассмотрим уровни клиента и уровни сервера.

Идея взаимодействия состоит в том, что функция, которая в данном случае называется Server Func, формально при чтении кода не должна вызывать ассоциации с сервером. С точки зрения клиента, осуществляется как бы выполнение этой функции. Функция имеет два параметра – символьный Hello и целочисленный 123. И результат должен быть присвоен некоему объекту J. На самом деле на клиенте функционирует специальный слой, который называется промежуточным и транслирует при переводе этой программы в промежуточный код из так называемого верхнего слоя (Top Layer), представляющего собой исходный текст на том или ином языке программирования (в данном случае это язык С), который транслирует этот вызов в некий внутренний вызов и упаковывает его нужным образом. Этот специализированный механизм называется Proxy-клиент. Он осуществляет трансляцию и упаковку этого вызова процедуры в обращение к другому компьютеру (серверу) с нужными параметрами, которые переупаковываются, меняют свои имена. Происходит передача некоего указателя на область памяти (*str) и некоего целочисленного значения v, с кодом, который у нас имеется на клиенте, осуществляется передача его после соответствующей упаковки серверу, Stub серверу, т. е. специальный функциональный компонент сервера осуществляет преобразование этого запроса во внутренний запрос сервера, организацию процедуры, заданной клиентом, и активизацию этой процедуры на сервере с заданными параметрами. Вычисление значений с переданными аргументами происходит путем подстановки вместо параметров их значений. Вычисление связано с работой процедуры на сервере. После этого осуществляется обратная упаковка и передача клиенту в ответ на его запрос. На нижнем уровне (Bottom Layer) осуществляется передача данных по сети на соответствующем уровне. Ниже находятся все последующие протоколы сетевого стека.

В ходе обсуждения взаимодействия RPC – это один из весьма важных механизмов взаимодействия по сети, который принципиально важен для понимания технологии Remoting. Осуществляется взаимодействие между Proxy и Stub. Proxy – это подпрограмма, которую может вызывать клиент на сервере. Поэтому технология называется процедурой удаленного вызова. Proxy передает серверу запрос на вызов подпрограммы, которая работает на сервере, с заданными параметрами, и ждет ответа от сервера. После выполнения процедуры результат возвращается клиенту. При этом вызов Proxy с точки зрения кода клиента не отличается от вызова внутренней подпрограммы или метода. Фактически эта логика взаимодействия удаленного вызова инкапсулируется внутри Proxy. Аналогично, но только на сервере, работает технология, связанная со Stub. Это тот код, который выполняется на сервере. Он получает от клиента запрос на вызов заданной подпрограммы. Осуществляется вызов подпрограммы, которая работает на сервере, а не на клиенте, как кажется клиенту. И результат, который записывается в переменную Result, автоматически после упаковки отправляется по сети на клиент. При этом Proxy и Stub создаются автоматически. Для этого, конечно же, требуется определенного рода описание открытых интерфейсов, т. е. сред взаимодействия между клиентом и сервером. Одним из примеров такого языка является IDL–Interface Definition Language, который используется в технологии брокеров объектных запросов (COBRA).

Итак, мы можем видеть три слоя взаимодействия, если абстрагироваться от сетевого уровня, где все просто описано с точки зрения кода, на уровне исходного текста программ – процедура на клиенте и процедура на сервере. На уровне Middle Layer происходит упаковка Proxy Stub клиента и упаковка параметров, выполнение процедуры на сервере после распаковки и передача упакованного результата через Middle Layer на клиент. Собственно, данные передаются на уровне Bottom Layer по протоколу передачи данных. Естественно, существует стек сетевых протоколов с целым рядом протоколов, которые лежат ниже перечисленных нами уровней процедурного взаимодействия.

Посмотрим, как осуществлялась революция объектных методов RPC в 1990-е гг. При этом объекты могут быть реализованы разными средами разработки и написаны на разных языках программирования.

Объектное RPC скрывает различия между объектами, которые разработаны в разных интегрированных средах и, возможно, на разных языках. В связи с этим сделан большой шаг вперед по сравнению с предыдущим подходом, который на самом деле достаточно жестко завязан на язык программирования. И, конечно же, по сути, объектного взаимодействия в 1980-е гг. в полной мере еще не было. При этом наиболее распространенными подходами следует считать подходы, основанные на компонентной модели COM c динамическим расширением Decom и COM+. И второй важный подход – CORBA. Это альтернативный подход, связанный с брокерами объектных запросов и использующий язык IDL, который описывает интерфейсы взаимодействия между различными объектами. Подход CORBA связан с Object Request Broker, которые реализуют функции, несколько похожие на Proxy и Stub, описанные ранее.

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

Рис. 9.8. Клиент-серверное взаимодействие по схеме COBRA

Итак, какие особенности можно выявить в объектных RPC, объектном подходе к удаленному вызову процедур, с точки зрения взаимодействии Proxy и Stub по сравнению с ранним подходом? Речь идет об объектном взаимодействии. Proxy и Stub выглядят как обычные объекты. Для клиента функция на С выглядит как локальная. Так же и объект при вызове будет выглядеть как локальный объект на клиенте. Но на самом деле этот объект осуществляет упаковку параметров и передачу их серверу. Этот процесс упаковки параметров и их передачи называется маршаллинг и является весьма существенным для. NET и Remoting, так как по сути означает передачу объекта через границу процесса.

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

Теперь обсудим, каким образом осуществляется взаимодействие между клиентом и сервером в RPC по объектной схеме. Как Proxy, так и Stub являются объектами и реализуют в полной мере объектно-ориентированное взаимодействие параметров Operation передачи от клиента серверу и параметров Reply возвращаемого значения от сервера клиенту. При этом взаимодействие между клиентом и сервером, кроме упаковки параметров и ответов, включает, что очень важно, передачу этих параметров через границу различных процессов (1 и 2), которые выполняются, возможно, в различных ОС или на различных машинах. Напомним, что процесс упаковки называется маршаллингом, процесс распаковки – анмаршаллингом. Если перейти от традиционной схемы объектно-ориентированного взаимодействия при реализации технологии удаленного вызова процедур RPC к той технологии, которая реализуется в среде Microsoft.NET и называется. NET Remoting, станет понятно, что взаимодействие организуется очень похоже.

Каким же образом осуществляется взаимодействие между клиентом и сервером через границы процессов и как при этом используются так называемые домены приложений? Рассмотрим это более подробно. При выполнении некоторой программы, написанной для. NET, естественно, следуя главе, в которой речь шла о среде. NET, выполнение это происходит в среде CLR. По сути, компоненты программ, которые реализуются и выполняются в этой среде, оттранслированы в код виртуальной машины. Microsoft Intermediate Language, зависящая от платформы, функционирует в терминах этого языка на той самой виртуальной машине, которая называется CLR машина. При этом загрузчик программы сначала создает хост CLR, по сути, экземпляр виртуальной машины и приложение машины, в которую по умолчанию загружаются сборки, необходимые для выполнения этой программы, и затем осуществляется передача управления этому процессу. В некоторых случаях в одном процессе может сосуществовать несколько различных доменов приложений. Среда CLR – виртуальная машина. NET может поддерживать независимое выполнение программ одного процесса в рамках нескольких доменов приложений. На рис. 9.9 представлен процесс, который на уровне операционной системы реализован в архитектуре приложений 32-разрядной машины Windows. При этом на уровне. NET осуществляется создание хоста CLR, в рамках которого могут функционировать в одном процессе несколько доменов приложений. Далее соотношение между процессами и доменами приложений выглядит следующим образом. В рамках одного и того же компьютера, скажем CLR, могут функционировать несколько процессов в архитектуре той же Windows 32. В каждом из них может быть также не один домен приложения, а несколько. Другой компьютер – это может быть сервер или другой клиент – также может иметь один или несколько процессов Windows 32, внутри которых также может быть несколько (в данном случае три) домена приложений.

Рассмотрим, каким образом осуществляется работа с удаленными объектами, расположенными на сервере? Со стороны клиента это выглядит точно так же, как и в среде. NET. Существует четкое разделение на взаимодействие по имени и взаимодействие по ссылке (Value и Reference). Если мы вспомним систему CPS, систему типизации, которая реализована для. NET, то увидим, что в рамках этой системы типизации существует изначальное четкое разграничение на две большие категории типов – Reference и Value. И обращение с объектами, обработка объектов этих больших категорий происходит различными способами. Напомним, что объекты классов категории Value, например, хранятся в стеке, при копировании создается физическая копия объекта, создается еще один объект стандартного размера, скажем, 4 или 2 байта, в зависимости от типа объекта. Он имеет фиксированный размер, и осуществляется физическое копирование значения. Если рассматривать объекты типа Reference, то осуществляется копирование ссылки, а не самого значения. Размер объекта, который имеет тип ссылку, изначально не определен, и на самом деле речь идем о том, что есть указатель на некую область памяти. Хранится в динамической памяти объект этого типа, т. е. взаимодействие между такого рода объектами, или маршаллинг, также происходит различными способами. То есть в. NET существует подход, который называется Marshal by Value и Marshal by Reference. Рассмотрим основные различия между этими подходами, а также их реализацию.

Рис. 9.9. Домены приложений в Windows

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

Итак, маршаллинг по значению разумен, целесообразен в тех случаях, когда, так же как и в случае объектов типа значения, речь идет о достаточно простых объектах – целочисленных, булевых или о тех объектах, которые редко претерпевают изменения во времени. Маршаллинг по ссылке предполагает передачу от сервера к клиенту параметров вызываемого метода, а не самого объекта. И методы объекта вызываются на стороне сервера. В случае маршаллинга по значению вызываются на стороне клиента, в случае маршаллинга по ссылке – на стороне сервера. В отношении маршаллинга по ссылке и по значению можно отметить следующую специфику: объект содержит ссылки на системные ресурсы, которые специфичны либо для процессора, либо для компьютера. Также объект содержит ссылки на большое количество других объектов на стороне сервера либо часто изменяет свое состояние. Если речь идет о маршаллинге по ссылке, то этот подход предпочтителен для сложных специфичных объектов конкретного процесса или компьютера, для объектов с большим количеством ссылок или для объектов, которые часто изменяют свое состояние. При работе с корпоративными системами также целесообразен маршаллинг по ссылке.

Рассмотрим явное создание объекта как вариант клиент-серверного взаимодействия по технологии Remoting. Здесь мы уже видим в примере кода, что явно используется метод маршаллинга объекта класса Remoting Services. То есть в пространстве имен. NET существует класс Remoting Services, который имеет ряд методов, связанных с реализацией объектов и передачей параметров от клиента серверу различными способами. Итак, при явном создании объекта осуществляется прежде всего создание некоего объекта, вызов конструктора, оператор NEW для объекта Obj класса Server Object. Осуществляется вызов конструктора без параметра, и создается новый объект. После чего осуществляется маршаллинг с явной передачей именно этого объекта путем вызова метода Marshal класса Remoting Services с параметром Obj. Таким образом, объект на сервере создается явно. Он будет иметь имя srv_obj. И объект на сервере существует до тех пор, пока на него имеются ссылки. Реализация уничтожения ссылок явным образом осуществляется посредством вызова специального метода, того же класса Remoting Services, который называется Disconnect. При этом необходимо явно указывать, что речь идет об объекте Obj.

При явном создании объекта клиент может получить ссылку на этот серверный объект двумя способами – используя либо метод Get Object класса Activator (здесь необходимо преобразование к классу Server Object), либо оператор type of, который определяет объект по типу. Для этого явно указывается имя объекта, которое было ранее определено и его местоположение, – Localhost. Другой подход связан с определением типа объекта и явным указанием этого объекта таким же образом, как и в предыдущем методе, а затем созданием объекта явным образом посредством конструктора Server Object.

Далее следует рассмотреть вопрос явной активизации объектов на сервере. Момент создания объекта в этом случае определяется сервером. При этом речь идет уже о передаче не экземпляра объекта, а его типа. То есть имя присваивается не экземпляру, а типу. И для обработки каждого вызова удаленного метода может создаваться собственно новый экземпляр объекта. При этом используется метод Single Call. Здесь явно указывается имя объекта srv_obj и осуществляется вызов метода Register Service Type, т. е. определенный метод реализации сервиса на основе класса Remoting Configuration. Нужно сказать, что все вызовы удаленного метода могут обрабатываться одним и тем же объектом, сервером, при этом используется метод Single в отличие от предыдущего Single Call. Клиент работает с удаленным объектом полностью аналогично предыдущему случаю. Другая форма взаимодействия между клиентом и сервером основана на активизации объектов клиента. При этом момент создания объекта определяется уже не сервером, а клиентом, и на сервере в этом случае может быть создано много объектов. В этом случае сервер объекта уникально однозначно определяется явным указанием имени компьютера. Мы видим, что осуществляется передача параметра методу Register Activated Service Type, т. е. осуществляется регистрация указанного типа сервиса с параметром того самого объекта типа «сервер», к которому реализуется обращение. При этом, по сути, мы работаем в том же пространстве имен Remoting с тем же классом Remoting Configuration, но другим образом определяем конфигурацию взаимодействия между клиентом и сервером. При активизации объектов клиентом на сервере клиент должен вначале осуществить регистрацию типа объекта с учетом его расположения на сервере, а затем создать объекты, для каждого обращения создается объект (Proxy), который осуществляет инкапсуляцию методов на сервере. Итак, мы используем метод Register Activator Client Type класса Remoting Configuration с явным указанием, что тип объекта расположен на сервере, и явным указанием этой машины. После чего для каждого вызова создается свой объект класса Server Object. По сути, это не совсем объекты, это Proxy. Но для каждого из них осуществляется свой вызов оператора New.

Последнее, что будет обсуждаться касательно Remoting, – это процедура сборки мусора. Вообще, процедура сборки мусора крайне важна для больших объектных систем. Здесь речь идет о том, что существует большое количество объектов типа «ссылки». Следует напомнить, что в. NET, в CTS – системе типизации, существуют два больших подкласса объектов – ссылки и значения. Если рассматривать корпоративные системы, то очевидно, что для реализации распределенных приложений, которые используют большое количество сложных объектов, а вместе с тем эти объекты имеют сложную структуру и динамически взаимодействуют друг с другом, целесообразно использовать типы-ссылки. В связи с этим часто возникают ситуации, когда не вполне корректно уничтожается информация о значении самого типа-ссылки при уничтожении собственно объекта этого типа. То есть не всегда разрывается связь между именем и значением объекта, на которое указывает ссылка с этого имени. Для уничтожения такого рода висячих ссылок, т. е. ссылок, указывающих на некорректную область памяти, которая уже освобождена и не содержит значения типа «ссылки», существует стандартный процесс сборки мусора.

По сути, эта технология характерна для большого количества программных инструментов, программных сред и реализована впервые достаточно давно, в частности одни из первых реализаций были связаны с языками функционального программирования, которые также поддерживают динамические структуры данных (например, LISP). Естественно, в Microsoft.NET, среде, которая призвана поддерживать работу с большим количеством языков программирования, распределенных сложных корпоративных программных систем, актуальность сборки мусора существенно возрастает в связи с частой сменой состояния и значений объектов. Конечно, имеет смысл и для технологии Remoting, и для технологии, которая поддерживает определенное взаимодействие компонентов таких систем, осуществить грамотный оптимальный и достаточно эффективный подход к сборке мусора. И здесь существуют разные подходы: обычный подход к сборке мусора в целом в среде. NET и поход, который связан с реализацией механизмов на основе. NET Remoting.

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

Что касается подхода Remoting, то здесь используется механизм аренды. Существует определенный интервал времени, который определяется для каждого серверного объекта. Каждому серверному объекту ставится в соответствие объект специального вида, который имеет интерфейс лизинга. И выглядит следующим образом: существует для маршаллинга по ссылке класс, который определяется как класс Marshal by Ref Object и содержит виртуальный объект, собственно и реализующий инициализацию процедуры обслуживания сборщика мусора. При этом интерфейс лизинга внутри класса осуществляет вычисление времени аренды для каждого объекта, который поставлен в соответствие и для которого существует возможность определения и обновления срока аренды, если такая возможность предоставляется.

На этом рассмотрение реализации технологий распределенных вычислений в среде. NET завершается. Мы познакомились с общим принципом распределенных вычислений, обсудили различие между подходом с сохранением состояний и подходом без сохранения состояний, а также подходом, который связан с Loosely Coupled и Tightly Coupled моделями взаимодействия. Оценили эффективность сильно связанной и большую универсальность слабо связанной модели взаимодействия объектов. Рассмотрели эволюцию архитектур, которые связаны с объектным и дообъектным подходами обмена информацией между клиентом и сервером по технологии RPC. Общим для этих подходов является наличие Proxy и Stub как механизмов упаковки и передачи параметров между клиентом и сервером. При упаковке речь идет о маршеринге, при распаковке – об анмаршаллинге. В объектном подходе имеет место инкапсуляция объектов, т. е. изоляция технологий сред взаимодействия и конкретных языков программирования, на которых реализуются процедуры, методы или функции для клиентов и серверов.

При этом инкапсуляция осуществляется на основе модели объектного вида – это либо COM-модель, либо модель типа CORBA – брокеров объектных запросов, либо компонентная модель, в более позднем варианте представляющая собой динамическую COM-модель, на основе которой реализуется подход, связанный с Remoting. Этот подход основан на использовании жестких протоколов, которые обеспечивают большую безопасность и надежность взаимодействия между компонентами корпоративных систем и распределенных приложений. При более мягком подходе, связанном с веб-сервисами, осуществляется слабосвязанная модель взаимодействия, которая в меньшей степени связана с. NET Remoting.

Как Remoting, так и более поздние технологии, с нашей точки зрения, основаны на интерфейсе, связанном с веб-формами, и существенно его используют. Более поздние технологии – это технологии веб-сервисов, речь о которых пойдет более подробно в следующей главе, и технологии, которые связаны с подходом WCF – Windows Communications Foundations. Эти технологии призваны реализовать подходы, связанные с клиент-серверным взаимодействием на основе более открытых протоколов и объектного распределенного взаимодействия в архитектуре клиент – сервер. Речь идет о сервисно-ориентированной архитектуре и таких протоколах, как SOA, HTTP. Более подробно этот вопрос будет освещен позднее.

Более 800 000 книг и аудиокниг! 📚

Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением

ПОЛУЧИТЬ ПОДАРОК