oldi

Распределенные вычисления и технологии Inprise

Часть 3. Организация распределенных вычислений с помощью Inprise Entera

Наталия Елманова

1. НАЗНАЧЕНИЕ И СОСТАВ INPRISE ENTERA

2. СОЗДАНИЕ СЕРВЕРОВ ДОСТУПА К ДАННЫМ И КЛИЕНТСКИХ ПРИЛОЖЕНИЙ С ПОМОЩЬЮ ENTERA 3.2 И DELPHI 3/C++BUILDER 3 ENTERPRISE

   2.1. КОНФИГУРАЦИЯ И ЗАПУСК ENTERA BROKER

   2.2. КОНФИГУРАЦИЯ ИСТОЧНИКА ДАННЫХ И СЕРВЕРА

   2.3. СОЗДАНИЕ КЛИЕНТСКОГО ПРИЛОЖЕНИЯ С ПОМОЩЬЮ DELPHI ИЛИ C++BUILDER ENTERPRISE

   2.4. ПЕРЕДАЧА ПАРАМЕТРОВ НА СЕРВЕР

3. РЕАЛИЗАЦИЯ ВЫЗОВОВ УДАЛЕННЫХ ПРОЦЕДУР (RPC). СОЗДАНИЕ СЕРВЕРОВ ФУНКЦИОНАЛЬНОСТИ И КЛИЕНТСКИХ ПРИЛОЖЕНИЙ

   3.1. СОЗДАНИЕ DEF-ФАЙЛА

   3.2. ГЕНЕРАЦИЯ КОДА ДЛЯ СЕРВЕРА И КЛИЕНТА

   3.3. СОЗДАНИЕ СЕРВЕРНОЙ ЧАСТИ (DELPHI)

   3.4. СОЗДАНИЕ СЕРВЕРНОЙ ЧАСТИ (C/C++)

   3.5. ТЕСТИРОВАНИЕ СЕРВЕРА ФУНКЦИОНАЛЬНОСТИ

   3.6. СОЗДАНИЕ КЛИЕНТСКОГО ПРИЛОЖЕНИЯ (DELPHI)

   3.7. СОЗДАНИЕ КЛИЕНТСКОГО ПРИЛОЖЕНИЯ (C/C++)

   3.8. СОЗДАНИЕ КЛИЕНТСКОГО ПРИЛОЖЕНИЯ (VISUAL BASIC)

4. УПРАВЛЕНИЕ ФУНКЦИОНИРОВАНИЕМ ИНФОРМАЦИОННОЙ СИСТЕМЫ ПРЕДПРИЯТИЯ С ПОМОЩЬЮ INPRISE APPCENTER

   4.1. ОБЗОР APPCENTER

   4.2. ИСПОЛЬЗОВАНИЕ APPCENTER

   4.3. СОЗДАНИЕ И РЕДАКТИРОВАНИЕ КОНФИГУРАЦИЙ

   4.4. МОНИТОРИНГ ОБЪЕКТОВ

В предыдущей статье данного цикла была рассмотрена одна из самых недорогих технологий организации распределенных вычислений — технология Microsoft COM (точнее, ее расширение — COM+, реализованное в продукте Microsoft Transaction Server). Отметим, однако, что возможности создания распределенных систем ограничиваются не только использованием COM-технологии и соответственно MIDAS-ориентированными серверами. Нередко с целью обеспечения повышенной надежности серверы функциональности разрабатывают для платформ, отличных от Windows, и в этом случае используются технологии, отличные от COM. В данной статье будет рассмотрено создание серверов функциональности с помощью Inprise Entera, представляющего собой сервер приложений, функционирующий на многих платформах, таких как AIX, HP-UX, Solaris, Windows NT. Если говорить более точно, Entera представляет собой набор сервисов и утилит для создания и эксплуатации серверов функциональности и их клиентов, при этом и серверы, и клиенты могут быть созданы на различных языках программирования и для различных платформ. Это позволяет создавать многоуровневые системы в гетерогенной среде, где не только серверы баз данных, но и любые другие серверы функциональности могут выполняться под управлением платформ, отличных от Windows (например, на UNIX-платформах), что позволяет выбрать наиболее оптимальное для предприятия сочетание удобства, масштабируемости и надежности.

1. Назначение и состав Inprise Entera

Основное назначение серверов функциональности, созданных на базе Entera, — предоставлять содержащим только интерфейс пользователя «тонким» клиентским приложениям те или иные услуги, например, проведение сложных расчетов или доступ к данным, содержащимся на серверах баз данных. Являясь серверами доступа к данным (или иным сервером функциональности) для клиентского приложения, серверы на базе Entera могут быть, в свою очередь, клиентами серверных СУБД. Таким образом, с использованием Entera возможно построение трехзвенной системы, где в среднем звене содержатся средства доступа к данным, а также, при необходимости, бизнес-правила, в том числе те, что оформлены в виде исполняемых файлов, выполнение которых инициируется при необходимости. При этом нередко среднее звено состоит из комплекса серверов приложений, функционирующих на нескольких компьютерах, нередко под управлением различных операционных систем (рис. 1).

Entera поддерживает как стандарт распределенных вычислений DCE (Distributed Computing Environment), так и обмен данными между клиентом и сервером функциональности непосредственно с помощью протокола TCP/IP (только версия 3.2), позволяя при этом создавать клиентские приложения с помощью Delphi, Visual Basic, PowerBuilder, Smalltalk, Visual C++, Java, COBOL, C, C++, а также средств разработки 4-го поколения (в состав Entera входят соответствующие генераторы клиентского и серверного stub-кода). Поддерживается также широкий спектр серверных СУБД: Oracle, Sybase, Informix, Ingres, IBM DB2, Microsoft SQL Server (пользователям Entera доступны соответствующие сервисы доступа к данным, представляющие собой надстройки над клиентскими частями этих серверных СУБД).

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

Entera Broker предоставляет клиентскому приложению список доступных в сети сервисов, оформленных в виде объектов, и находит для обратившегося клиента в этом списке нужный из них. Entera Broker представляет собой, по существу, так называемый Directory Service.

Сервисы безопасности (Security Services) обеспечивают доступ пользователей к этим объектам в соответствии с их правами (их обсуждение выходит за рамки данной статьи).

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

Помимо стандартного комплекта Entera Developers Package разработчикам доступен ряд дополнительных продуктов: DCE Adapter — средство, предоставляющее возможность использования DCE клиентскими приложениями; Entera/Fx — набор утилит, включающих дополнительные средства повышения безопасности, средства равномерного распределения загрузки серверов приложений и др. Подробности о комплектах поставки и дополнительных продуктах можно узнать на Web-сайте www.inprise.com.

В начало

В начало

2. Создание серверов доступа к данным и клиентских приложений с помощью Entera 3.2 и Delphi 3/C++Builder 3 Enterprise

В типичных информационных системах с использованием Entera обычно имеется три звена:

1. Сервер баз данных.

2. Среднее звено, содержащее бизнес-правила, определяющие, каким образом можно получить данные, которые требуются приложению. Приложение, использующее эти данные, обращается к ним посредством Entera. В некоторых случаях правила могут быть сосредоточены в исполняемом файле, называемом сервером функциональности (functionality server), и этот сервер может обращаться к другому приложению среднего звена, поставляющему данные с сервера. Приложений среднего звена может быть несколько в зависимости от потребностей.

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

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

Наряду с версией Delphi и C++Builder Client/Server Suite имеются версии Delphi и C++Builder Enterprise, позволяющие создавать «тонкие» клиентские приложения для сервера приложений Inprise Entera c помощью компонентов TEnteraConnection и TEnteraProvider. Использование этих средств разработки будет рассмотрено далее.

В качестве примера рассмотрим использование Entera для Windows NT (использование Entera для UNIX требует примерно тех же приемов).

В начало

В начало

2.1. Конфигурация и запуск Entera Broker

Для создания сервера следует в первую очередь запустить Entera Broker. Типичный командный файл для запуска брокера выглядит следующим образом:

start "Entera Broker" broker -e broker.env
Команда start предназначена для создания процесса, в котором будет выполняться брокер. "Entera Broker" — заголовок окна, созданного командой start. Третий параметр — имя исполняемого файла broker.exe из каталога Entera\TCP. Параметр -e означает использование файла конфигурации, имя которого указано в последнем параметре команды. Этот файл имеет примерно следующий вид:
DCE_BROKER=elmanova, 16000
DCE_LOG=CLIENT.LOG
DCE_DEBUGLEVEL=D,D

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

Для успешного запуска брокера следует иметь в одном каталоге файлы broker.env, broker.exe, clistart.exe (надстройка над ODBC, обеспечивающая доступ к данным и фактически представляющая собой собственно сам сервер доступа к данным) и odet30.dll (библиотека, содержащая функции Entera API для Windows NT). Иногда бывает нужно, чтобы переменная окружения ODEDIR указывала на каталог Entera\TCP:

Set ODEDIR=D:\OpenEnv\Entera\Tcp

Окно запущенного брокера представляет собой стандартное окно 32-разрядного консольного приложения.

Отметим, что, если используется Entera 3.2 для Windows NT, брокер должен выполняться под управлением именно Windows NT; если используется Entera 3.2 для другой платформы — все выполненные выше действия следует выполнить для этой платформы (отличия здесь невелики, так как в основном здесь используются обычные команды операционной системы для установки значений переменных среды и запуска приложений). Например, в случае UNIX все команды можно выполнить в терминальном режиме или внутри терминального окна, если используется какая-нибудь графическая среда.

В начало

В начало

2.2. Конфигурация источника данных и сервера

Теперь можно приступить к созданию сервера доступа к данным. Сразу же отметим, что этот сервер не обязан находиться на том же самом компьютере, где запущен брокер; кроме того, данный сервер может выполняться под управлением Windows 95/98, что неоднократно проверено экспериментально.

В качестве источника данных используем каталог DBDEMOS или BCDEMOS, описав его в Control Panel как ODBC-источник типа dBase 5 с именем edemo.

Если данный компьютер не содержит такого каталога, может подойти любой другой ODBC-источник. Отметим, что компьютер, содержащий сервер доступа к данным, вовсе не обязан содержать Delphi, С++Builder или иное средство разработки. В принципе, он может управляться c операционной системой, отличной от Windows, и в этом случае может потребоваться по-другому конфигурировать доступ к данным (например, настроив соответствующим образом клиентскую часть какой-либо серверной СУБД).

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

Создадим простейший пример такого скрипта для таблицы Animals.dbf из каталога DBDEMOS:

select_animals:
SELECT NAME,SIZE,WEIGHT,AREA FROM ANIMALS;

insert_animals:
INSERT INTO ANIMALS (NAME,SIZE,WEIGHT,AREA)
VALUES($NAME[CHAR],$SIZE[DOUBLE],$WEIGHT[DOUBLE],$AREA[CHAR]);

delete_animals:
DELETE FROM ANIMALS 
WHERE NAME='$NAME';

update_animals:
UPDATE ANIMALS SET NAME= '$NAME', SIZE='$SIZE', WEIGHT='$WEIGHT',
AREA= '$AREA'
WHERE NAME='$NAME';

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

SET DB_LOGIN= 
SET DB_PWD= 
start   "Demo server" clistart -d edemo -s demo -e server.env -q 
anim.sql

Первые две строки устанавливают переменные среды, проверяемые сервером баз данных. В третьей строке с помощью команды start в окне с именем "Demo server" запускается утилита clistart — сервер доступа к данным, использующий ODBC-сервисы. Параметр этой утилиты -d указывает на имя ODBC-источника, созданного ранее. Параметр -s присваивает серверу имя demo. Параметр -e указывает на имя файла конфигурации. Параметр -q указывает на имя SQL-скрипта.

Файл конфигурации может выглядеть следующим образом:

  DCE_BROKER=elmanova, 16000
  DCE_LOG=SERVER.LOG 
  DCE_DEBUGLEVEL=D,D В 

В первой строке этого файла указывается, где выполняется брокер.

В результате выполнения этого командного файла сервер будет загружен в оперативную память.

Окно сервера также представляет собой стандартное окно запущенного 32-разрядного консольного приложения.

Отметим, что при использовании другого способа доступа к данным для создания сервера следует использовать соответствующую надстройку над клиентской частью серверной СУБД. Например, в случае доступа к Oracle такая надстройка называется orastart.exe, и в качестве параметра -d в этом случае указывается имя TNS-псевдонима соответствующей базы данных.

При создании сервера доступа к данным на платформе, отличной от Windows, следует использовать соответствующие версии утилит типа orastart. Команды и командные файлы также должны быть приведены в соответствие правилам используемой операционной системы. Выполнять их можно также в терминальном режиме или в терминальном окне — сервер доступа к данным не обладает пользовательским интерфейсом (но может создавать log-файлы, что обычно и используется).

В начало

В начало

2.3. Создание клиентского приложения с помощью Delphi или C++Builder Enterprise

После создания и запуска сервера доступа к данным можно приступить к созданию клиентского приложения.

Запустим Delphi 3 Enterprise (или C++Builder 3 Enterpise) и создадим новое приложение. На главной форме приложения поместим компоненты TEnteraConnection, TEnteraProvider, TClientDataset, TDataSource, TDBGrid и TDBNavigator. Установим свойство SQLFile компонента TEnteraConnection равным имени SQL-скрипта (его следует скопировать на компьютер, где будет функционировать клиент). Установим свойство ConfigFile этого же компонента равным имени файла окружения:

DCE_BROKER=elmanova, 16000
DCE_LOG=client1.LOG
DCE_DEBUGLEVEL=D,D

Использование этого файла необходимо для того, чтобы клиент мог найти брокер в сети.

СвойствоTransportName компонента TEnteraConnection должно быть установлено равным tmTCP. Cвойство ServerName должно содержать имя сервера (значение параметра -s).

Далее свойство Server компонента TEnteraProvider следует установить равным имени компонента TEnteraConnection. После этого следует выбрать из выпадающих списков значения свойств SelectRPC, InsertRPC, DeleteRPC, UpdateRPC.

Далее следует установить свойство Provider компонента TClientDataSet равным имени компонента TEnteraProvider. Свойство RemoteServer следует оставить пустым (в отличие от случая использования этого компонента с серверами, управляемыми MIDAS).

Теперь можно установить свойство Active этого компонента равным true и связать его с источником данных и интерфейсными элементами формы (рис. 4. )

Теперь можно сохранить проект, скомпилировать и запустить его.

В начало

В начало

2.4. Передача параметров на сервер

Предположим, нам нужно выполнить параметризованный запрос:

select_animals:
SELECT NAME,SIZE,WEIGHT,AREA FROM ANIMALS WHERE NAME=$NAME[CHARACTER];

Внесем соответствующие изменения в SQL-скрипт и перезапустим сервер.

Если теперь в клиентском приложении раскрыть список подсвойств SelectRPC компонента TEnteraProvider и выбрать подсвойство Params, можно просмотреть список всех параметров запроса и обнаружить, что параметр NAME изменил значение своего свойства ParamType на ptInput.

Модифицируем клиентское приложение, добавив компонент TEdit и кнопку.

Добавим обработчик события, связанный с нажатием на эту кнопку. Код для С++Builder при этом будет выглядеть так:

void __fastcall TForm1::Button1Click(TObject *Sender )
{
ClientDataSet1->Close();
EnteraProvider1->SelectRPC->Params->Items[0]->Value=Edit1->Text;
ClientDataSet1->Open();
}

Соответствующий код для Delphi выглядит так:

procedure TForm1.Button1Click(Sender: TObject);
begin
ClientDataSet1.Close;
EnteraProvider1.SelectRPC.Params[0].Value:=Edit1.Text;
ClientDataSet1.Open;
end;

Теперь можно сохранить, скомпилировать и запустить клиентское приложение.

Отметим, что создание сервера доступа к данным с использованием стандарта DCE (Distributed Computing Environment), предоставляющего доступ к данным, и клиентского приложения с помощью Delphi/C++Builder Enterprise мало чем отличается от создания сервера и клиента с использованием непосредственного доступа с помощью TCP/IP.

Для создания DCE-сервера следует иметь DCE-версии файлов clistart.exe (или orastart.exe и т.д.) и odet30.dll. Следует также позаботиться о корректных значениях переменных окружения ODEDIR и PATH:

SET ODEDIR=C:\OPENENV\ENTERA\DCE
PATH=%ODEDIR%\BIN;%PATH%

Файл конфигурации в данном случае имеет расширение DAP (Distributed Application Profile) и имеет примерно следующий вид:

[DCEApp]
Broker=ncan_in_tcp:elmanova[]
LogFile=client.log
LogLevel=3

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

Перед запуском сервера следует запустить брокер:

SET ODEDIR=C:\OPENENV\ENTERA\DCE
PATH=%ODEDIR%\BIN;%PATH%
start "Entera Broker" brk

Для запуска сервера следует выполнить команду:

start clistart -d edemo -e server.dap -q anim.sql 

(в случае использования ODBC — источника данных) или

start orastart -d TEST1 -e server.dap -q ora1.sql

(в случае использования ORACLE).

Создание DCE-клиента с помощью Delphi/C++Builder Enterprise практически не отличается от создания TCP-клиента. Основные отличия заключаются в другом значении свойства TransportMode компонента TEnteraConnection — оно должно быть равно tmDCE, и в выборе другого имени конфигурационного файла (сlient.dap), имеющего примерно следующий вид:

[DCEApp]
Broker=ncan_in_tcp:ws13[]
LogFile=dbserv.log
LogLevel=3

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

Как протестировать работу брокера и убедиться, что при наличии нескольких серверов в сети подключение клиентов к ним производится случайным образом (что позволяет осуществить баланс загрузки серверов)? Самый простой тест может заключаться в использовании доступа к каким-либо локальным таблицам с помощью серверов доступа к данным (например, той же самой таблицы Animals.dbf). Если в локальных версиях этих таблиц, содержащихся на разных компьютерах, где имеются серверы функциональности, будут содержаться разные данные, то каждый раз при запуске клиентского приложения в интерфейсных элементах формы будут также отображаться разные данные. Можно также поместить на форму клиентского приложения какой-нибудь интерфейсный элемент, осуществляющий установку и разрыв соединения с сервером, чтобы не перезапускать клиентское приложение.

В заключение отметим, что создание клиентских приложений может быть осуществлено не только с помощью Delphi/C++Builder Enterprise, но и при помощи многих других средств разработки, в том числе 16-разрядных (например, SQL Windows, Visual Basic, Delphi 1.0 или Delphi 2.0 Desktop). В этом случае следует использовать для соответствующего языка программирования генератор stub-кода, содержащего вызовы удаленных процедур, связанные с выполнением SQL-запросов (он входит в комплект поставки Entera и называется Object Interface Generator), и затем встраивать сгенерированный код в клиентское приложение, то есть использовать стандартные методы создания клиентских приложений, рассмотренные в следующем разделе. Компоненты TEnteraConnection и TEnetraProvider фактически просто реализуют функциональность, которая в ином случае содержалась бы в сгенерированном stub-коде.

В начало

В начало

3. Реализация вызовов удаленных процедур (RPC). Создание серверов функциональности и клиентских приложений

Помимо функциональности, связанной с доступом к базам данных, можно использовать Entera для реализации любой другой функциональности, то есть использовать RPC (Remote Procedure Calls — вызовы удаленных процедур) для удаленного доступа к функциям, осуществляющим любые другие действия (например, расчеты).

Отметим, что RPC являются основой механизма обмена данными между клиентом и сервером в рассмотренных выше примерах. Генерация этих вызовов осуществляется неявно при использовании компонента TEnteraProvider.

Ниже будут рассмотрены примеры явного вызова RPC (так называемые Simple RPC Calls). В этом случае следует создать stub-код для сервера и клиента; напомним, что вызовы удаленных процедур осуществляются за счет обмена пакетами данных (эта процедура иногда называется маршалингом, или маршрутизацией) между двумя stub-объектами в адресных пространствах сервера и клиента (подробнее об этом рассказано в первой статье данного цикла).

С целью иллюстрации этой процедуры создадим простейший TCP-сервер с помощью Entera 3.2.

В начало

В начало

3.1. Создание DEF-файла

Рассмотрим какую-либо функцию, написанную на Pascal, например, для вычисления синуса путем разложения в ряд:

function sin1(x: Double): Double;
VAR I:INTEGER; R:DOUBLE;SL:DOUBLE;XX:DOUBLE;
CONST DELTA=0.0001 ;
begin
SL:=X;  I:=1;
R:=0;  XX:=X*X;
WHILE (ABS(SL)>DELTA) DO
BEGIN
R:=R+SL;
SL:=-(SL*XX/(2*I))/(2*I+1);
inc(i);
END;
result:=R;
end;

Реализация ее с помощью C++ выглядит так:

double sin1(double x)
{
 int ii; double xx,r,sl,f,delta=0.0001;
 sl=x; ii=1; r=0; xx=x*x;
 f= fabs(sl);
 while (f>delta)
 {
 r=r+sl;
  sl=-(sl*xx/(2*ii))/(2*ii+1);
  f=fabs(sl);
  ii=ii+1 ;
  }
 return(r);
}

Создадим простейшее приложение для тестирования этой функции:

unit SINTST;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 StdCtrls, Buttons, TeEngine, Series, ExtCtrls, TeeProcs, Chart,a1;

type
 TForm1 = class(TForm)
  Chart1: TChart;
  Series1: TFastLineSeries;
  BitBtn1: TBitBtn;
  procedure BitBtn1Click(Sender: TObject);
 private
  { Private declarations }
 public
  { Public declarations }
 end;

var
 Form1: TForm1;

implementation



{$R *.DFM}

function sin1(x: Double): Double;
VAR I:INTEGER; R:DOUBLE;SL:DOUBLE;XX:DOUBLE;
CONST DELTA=0.0001 ;
begin
SL:=X;  I:=1;
R:=0;  XX:=X*X;
WHILE (ABS(SL)>DELTA) DO
BEGIN
R:=R+SL;
SL:=-(SL*XX/(2*I))/(2*I+1);
inc(i);
END;
result:=R;
end; {sin1}


procedure TForm1.BitBtn1Click(Sender: TObject);
VAR I:INTEGER;X:DOUBLE;Y:DOUBLE;
begin
FOR I:=1 TO 270 DO
BEGIN
X:=0.1*I;
//Y:=SIN1(I);
Y:=sin1(X);
CHART1.SERIES[0].ADDXY(X,Y,FLOATTOSTR(X),clwHITE);
END
end;

end.

Предположим, нам нужно разделить это приложение на сервер функциональности, вычисляющий синус, и «тонкий» клиент, рисующий график этой функции. В этом случае создание сервера функциональности следует начать с определения его интерфейса, для чего следует создать DEF-файл с описанием интерфейса этой функции на языке IDL (Interface Definition Language); вспомним, что IDL фактически представляет собой стандарт описания интерфейсов и все его диалекты похожи друг на друга.

[
uuid(cdf19a00-22c8-11d2-a36c-008048eb72de),
version(1.0)
]
interface a1{
double sin1(
[in] double x);
}

Этот код присваивает серверу уникальный код UUID (Universal Unique Identifier), который можно сгенерировать с помощью алгоритма, определенного Open Software Foundation и реализованного в ряде утилит и функций (например, есть функция Windows API CoCreateGUID, реализующая этот алгоритм). В случае TCP-сервера в действительности он не используется, так же как и номер версии сервера, но используется в случае DCE-сервера. Затем объявляется интерфейс сервера, в котором можно описать несколько функций (в нашем случае она одна).

При написании DEF-файлов следует учитывать соответствие типов данных в DEF-файлах и используемых для создания серверных и клиентских частей языков программирования:

Объявления в DEF-файле Входные параметры Pascal Выходные параметры Pascal
Short x x: Smallint var x: Smallint
long x x: Longint var x: Longint
int x x: Integer var x: Integer
float x x: Single var x: Single
double x x: Double var x: Double
char x x: Char var x: Char
В начало

В начало

3.2. Генерация кода для сервера и клиента

Для создания серверной и клиентской части распределенной системы на базе Entera следует сгенерировать stub-код («заглушку»), превращающую простые вызовы функций в вызовы удаленных процедур. В частности, при использовании удаленной функции следует сообщить компилятору о том, что ее реализация находится не в клиентском приложении, а на удаленном сервере. «Заглушка» нужна для того, чтобы компилятор мог найти нужную функцию, а ее реализация представляет собой код, осуществляющий вызов удаленных процедур.

Генерация stub-кода для сервера и клиента осуществляется автоматически с помощью утилиты rcmake.exe. Ee параметры в случае любой 32-разрядной версии Delphi выглядят так:

rpcmake -d myserv.def -c delphi2.0 -s delphi2.0

В случае С или С++ параметры rpcmake выглядят следующим образом:

rpcmake -d myserv.def -c c -s c

Здесь параметр -d - имя DEF-файла, -c — язык, для которого должен быть сгенерирован клиентский stub-код, -s — язык, для которого должен быть сгенерирован серверный stub-код (eстественно, эти языки могут быть разными).

В каталоге Entera\TCP\BIN имеется также утилита rpcmgui.exe, представляющая собой GUI-оболочку для rpcmake.exe.

Наиболее близким описанному выше процессу генерации кода из знакомых Windows-программистам процедур является, пожалуй, генерация stub- и proxy-кода Microsoft Visual C++ для динамически загружаемых библиотек, используемых в COM-сервере и COM-клиенте, с помощью компилятора MIDL на основании IDL-описания интерфейсов сервера. Отметим, что автоматическая генерация stub-кода на основании описания интерфейсов является сейчас общепринятым процессом при организации распределенных вычислений; создание такого кода «вручную» используется сегодня довольно редко.

В начало

В начало

3.3. Создание серверной части (Delphi)

В результате использования утилиты rpcmake.exe с парамерами, соответствующими выбору Delphi в качестве языка для сервера, получим следующие файлы: a1_c.pas (stub-код, который можно встраивать в клиентское приложение), a1_s.dpr (исходный текст консольного приложения для сервера функциональности), a1.pas — файл-заготовка, используемая при создании сервера, в который разработчику следует добавить код реализации функций (примерно так, как пишутся обработчики событий), a1.inc — код, содержащий объявления функций без их реализации (секция интерфейса).

Код для сервера a1_s.dpr, сгенерированный этой утилитой, выглядит следующим образом:

{
$APPTYPE CONSOLE}
program a1_s;

uses SysUtils, ODET3020, a1;

procedure rpc_sin1(dce_table: PTable; socket: Integer);
var
	rv : Integer;
	x : Double;
begin
	x := dce_pop_double(dce_table,'x');
	dce_push_double(socket,'dce_result',sin1(x));
end;

procedure rpc_handle(func: PChar; table: PTable; socket: Integer);
begin
	if (StrComp(func,'sin1')=0) then
		rpc_sin1(table,socket)
	else
		dce_unknown_func(func, table, socket);
end;


{Constants and global variables follow}
const
	VARLEN = 100;
var
	ode_file : PChar;
	ode_server : PChar;
	dce_func : PChar;
	argarr : array[0..5] of array[0..VARLEN] of Char;
	argptrs : array[0..5] of PChar;
	argv : PChar;
	argc : Integer;
	dce_table : PTable;
	called_init_func : Integer;
	socket, rsocket, i, rv : Integer;
	msgstr : String;

begin {main}

	GetMem(ode_file,VARLEN);
	GetMem(ode_server,VARLEN);
	GetMem(dce_func,VARLEN);

	called_init_func := 0;

	FillChar(argarr,SizeOf(argarr),#0);
	FillChar(argv,SizeOf(argv),#0);

	for i := 0 to ParamCount + 1 do begin
		StrCopy(argarr[i],PChar(ParamStr(i)));
		argptrs[i] := @argarr[i];
	end; {for}

	argc := ParamCount + 1;
	argv := @argptrs;

	rv := parse_args(argc, argv, ode_file);

	if (rv=0) then begin
		Writeln('Env flag (-e) not set');
			if ParamCount > 1 then
				StrCopy(ode_file,PChar(ParamStr(ParamCount)));
	end;

	if (dce_setenv(ode_file,NIL,NIL) = 0) then begin
		msgstr := 'Set env '+ode_file^+' failed';
		WriteLn(msgstr);
		msgstr := 'Reason: '+dce_errstr;
		Writeln(msgstr);
		Halt(1);
	end;

	ode_server := dce_servername('a1');

	dce_checkver(2, 0);

	socket := dce_init_server(ode_file,ode_server);
	if (socket <= 0) then begin
		Writeln('setup server failed');
		Writeln('Reason: '+dce_errstr);
		dce_set_exit;
	end;

	while(True=True) do begin
		dce_table := dce_waitfor_call(socket,dce_func);
		if (Boolean(dce_should_exit) or Boolean(dce_err_is_fatal)) then
			Exit
		else begin
			if (Boolean(dce_server_is_ded)) then begin
				dce_spawn(socket,argc,argv,ode_file,ode_server);
				socket := dce_retsocket; (* save for future *)
			end;
			rsocket := dce_retsocket(); (* (old socket closed) *)
			rpc_handle(dce_func,dce_table,rsocket);
			dce_send(rsocket,dce_func);
			dce_recv_conf(rsocket);
			dce_release;
			dce_table_destroy(dce_table);
			if (dce_server_is_ded=0) then
				dce_close_socket(rsocket);
		end; {else}
	end; {while}

	FreeMem(ode_file,VARLEN);
	FreeMem(ode_server,VARLEN);
	FreeMem(dce_func,VARLEN);

	dce_close_socket(rsocket);
	dce_table_destroy(dce_table);

end.

Секция интерфейса a1.inc выглядит следующим образом:

function sin1(x: Double): Double;

Код реализации функций a1.pas имеет следующий вид (жирным шрифтом выделены строки, которые следует добавить разработчику):

unit a1;

interface

uses SysUtils, ODET3020;

{$include a1.inc}

implementation

function sin1(x: Double): Double;
VAR I:INTEGER; R:DOUBLE;SL:DOUBLE;XX:DOUBLE;
CONST DELTA=0.0001 ;
begin
SL:=X;  I:=1;
R:=0;  XX:=X*X;
WHILE (ABS(SL)>DELTA) DO
BEGIN
R:=R+SL;
SL:=-(SL*XX/(2*I))/(2*I+1);
inc(i);
END;
result:=R;
end; {sin1}

end. {unit}

Cервер можно скомпилировать из среды разработки или из командной строки, вызвав компилятор Pascal:

Dcc32 -b a1_s.dpr

Перед компиляцией проекта файл ODET3020.pas (интерфейс к ODET3020.DLL — библиотеке, содержащей Entera API) следует поместить в тот же каталог, что и компилируемый проект. Исполняемый файл также требует наличия этой библиотеки в каком-либо доступном каталоге.

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

В начало

В начало

3.4. Создание серверной части (C/C++)

В результате использования утилиты rpcmake.exe (или rpcmgui.exe) с парамерами, соответствующими выбору C или C++ в качестве языка для сервера, получим следующие файлы: a1_c.c (stub-код, который можно встраивать в клиентское приложение), a1_s.c (исходный текст консольного приложения для сервера функциональности), a1_s.h - h — файл для myserv_s.c, a1.h — h- файл, содержащий объявления функций без их реализации (используется в клиентском приложении). Реализацию этих функций (a1.c) следует создать разработчику.

Код для сервера a1.с, сгенерированный этой утилитой, выглядит следующим образом:

/*########################
# Server Proxy Procedure Code
# generated by rpcmake version2.0
# on Thursday, December 31, 1998 at 19:17:39
# 
# interface: a1 
# 

########################
# server stub routines #
########################*/
#ifdef __mpexl
#include "dceinc.h"
#else
#include 
#endif

#include 
#include 
#include 

#ifdef __cplusplus
	extern "C" {
#endif

/* RPC stub and stub handle definitions */
void rpc_handle (char *, struct table *, int);
void rpc_sin1 (struct table *, int);
#ifdef __cplusplus
	}
#endif



void rpc_sin1 (struct table *dce_table,int Socket)
{
	double x;
	int _i;

	double sin1(double);

	x = dce_pop_double(dce_table,"x");
	dce_push_double(Socket,"dce_result",
			sin1(x));
}

int main(int argc,char **argv)
{
	char *ode_file = NULL,*ode_server = NULL;
	char dce_func[VARLEN];
	struct table *dce_table;
	int called_init_func = 0;
	int socket,rsocket;

	if (!parse_args(&argc, argv,&ode_file)) {
		printf ("Env flag (-e) not set\n");
		ode_file = argc > 1 ? argv[argc-1] : (char *) NULL;
	}
	if (dce_setenv(ode_file,NULL,NULL) == 0) {
		fprintf(stderr,"Set env %s failed\n", ode_file);
		fprintf (stderr,"Reason: %s\n", dce_errstr());
		exit(1);
	}

	ode_server = dce_servername("a1");


	dce_checkver(2, 0);

	if ((socket = dce_init_server( ode_file,ode_server)) <= 0) {
		fprintf (stderr,"setup server failed\n");
		fprintf (stderr,"Reason: %s\n", dce_errstr());
		dce_set_exit();
	}

	while(1) {
		dce_table = dce_waitfor_call(socket,dce_func);
		if (dce_should_exit() ||
		  dce_err_is_fatal() )
			{break;
			}
		else {
			if (dce_server_is_ded()) {
				dce_spawn(socket,argc,argv,ode_file,ode_server);
				socket = dce_retsocket(); /* save for future */
			}

			rsocket = dce_retsocket(); /* (old socket closed) */
			rpc_handle(dce_func,dce_table,rsocket);
			dce_send(rsocket,dce_func);
			dce_recv_conf(rsocket);
			dce_release();
			dce_table_destroy(dce_table);
			if (!dce_server_is_ded()) {
				dce_close_socket(rsocket);
			}
		}
	}
	dce_close_socket(rsocket);
	dce_table_destroy(dce_table);

	return(0);
}

void rpc_handle(char *func,struct table *dce_table,
	int Socket)
{
	if (strcmp(func,"sin1")==0)
		(void)rpc_sin1(dce_table,Socket);

	else (void)dce_unknown_func(func, dce_table, Socket);

}
H-файл a1_s.h выглядит следующим образом:
/*************************************
*
* Server Header for a1
* Generated by rpcmake version 3.0
* on Thursday, December 31, 1998 at 19:17:39
*
**************************************/

#ifdef __cplusplus
	extern "C" {
#endif

extern double sin1(double );
#ifdef __cplusplus
	}
#endif

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

USEUNIT("A1_s.c");
USELIB("odet30.lib");
//-----------------------------------------------------------------
double sin1(double x)
{
 int ii; double xx,r,sl,f,delta=0.0001;
 sl=x; ii=1; r=0; xx=x*x;
 f= fabs(sl);
 while (f>delta)
 {
 r=r+sl;
  sl=-(sl*xx/(2*ii))/(2*ii+1);
  f=fabs(sl);
  ii=ii+1 ;
  }
 return(r);
} 

Отметим, что все функции, связанные с выделением памяти в обычном С-коде, следует заменить на соответствующие функции c префиксом dce_ (например, dce_malloc) из Entera API.

В начало

В начало

3.5. Тестирование сервера функциональности

Для тестирования сервера следует создать для него env-файл с описанием переменных окружения:

DCE_BROKER=elmanova,16000
DCE_DEBUGLEVEL=DEBUG,DEBUG
DCE_LOG=server.log

Далее следует запустить Entera Broker (если он еще не запущен), создав предварительно конфигурационный файл broker.env:

start broker -e broker.env

Затем следует создать и запустить командный файл для запуска сервера:

set odedir = c:\OpenEnv\Entera\TCP
start "IT IS A SERVER" a1_s -e server.env

Только после этого можно запускать или отлаживать клиентское приложение.

В начало

В начало

3.6. Создание клиентского приложения (Delphi)

Код, сгенерированный утилитой rpcmake для клиента Delphi (a1_c.pas), имеет следующий вид:

unit a1_c;

interface 

uses SysUtils, Classes, ODET3020;

function sin1(x: Double): Double;


implementation

function sin1(x: Double): Double;
var
	dce_table : PTable;
	socket : Integer;
	rv   : Integer;
begin
	dce_table := nil;
	dce_checkver(2,0);
	socket := dce_findserver('a1');
	if (socket > -1) then begin
		dce_push_double(socket,'x',x);
		dce_table := dce_submit('a1','sin1',socket);
	end;
	sin1 := dce_pop_double(dce_table,'dce_result');
	dce_table_destroy(dce_table);
end;

end.

Этот код заставляет клиентское приложение обращатьcя к удаленной функции как к локальной. В действительности этот код представляет собой серию вызовов удаленных процедур. Все интерфейсы функций, к которым обращается клиент, содержатся в файле odet30.pas (dceinc.h), а их реализация — в файле odet30.dll.

Создадим клиентское приложение для тестирования созданного сервера. Создадим новый проект, добавим в него сгенерированный модуль a1_c.pas (a1_c.c в случае С++Builder) и сошлемся на него и на odet3020.pas в модуле, связанном с главной формой приложения. На форму поместим интерфейсные элементы, необходимые для тестирования сервера (примерно те же, что и в тестовом примере, расмотренном выше; можно сделать копию этого проекта и внести в нее необходимые изменения).

Создадим обработчики событий, связанных с нажатием на кнопки, а также с созданием и уничтожением формы:

unit sin_cln1;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 StdCtrls, Buttons, TeEngine, Series, ExtCtrls, TeeProcs, Chart;

type
 TForm1 = class(TForm)
  Chart1: TChart;
  Series1: TFastLineSeries;
  BitBtn1: TBitBtn;
  procedure BitBtn1Click(Sender: TObject);
  procedure FormCreate(Sender: TObject);
  procedure FormDestroy(Sender: TObject);
 private
  { Private declarations }
 public
  { Public declarations }
 end;

var
 Form1: TForm1;

implementation

uses a1_c, odet3020;

 
{$R *.DFM}



procedure TForm1.BitBtn1Click(Sender: TObject);
VAR I:INTEGER;X:DOUBLE;Y:DOUBLE;
begin
FOR I:=1 TO 270 DO
BEGIN
X:=0.1*I;
Y:=sin1(X);
CHART1.SERIES[0].ADDXY(X,Y,FLOATTOSTR(X),clwHITE);
END;
end;

procedure TForm1.FormCreate(Sender: TObject);
 Var rv : integer;
 msg : array [0 .. 200] of char;
begin
 rv := dce_setenv ('client.env', nil, nil);
 if (rv = 0) then
 begin
  dce_error (msg);
  MessageDlg('TCP Error: ' + msg, mtInformation, [mbOK], 0);
  PostMessage(Handle, WM_QUIT, 0, 0);
 end;
end;


procedure TForm1.FormDestroy(Sender: TObject);
begin
dce_close_env;
end;

end.

Отметим, что при создании главной формы приложения следует вызвать процедуру dce_setenv из библиотеки odet3020.dll, указав имя конфигурационного файла client.env в качестве параметра. К моменту запуска клиента этот файл должен существовать примерно в следующем виде:

DCE_BROKER=elmanova, 16000
DCE_LOG=CLIENT.LOG
DCE_DEBUGLEVEL=D,D

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

В начало

В начало

3.7. Создание клиентского приложения (C/C++)

Код, сгенерированный утилитой rpcmake для клиента C/C++ (a1_c.c), имеет следующий вид:

/*########################
# Client Proxy Procedure Code
# generated by rpcmake version 3.0
# on Thursday, December 31, 1998 at 19:17:39
# 
# interface: a1 
# */

#include 
#if defined __mpexl || defined _MACINTOSH_
#include "dceinc.h"
#else
#include 
#endif

double sin1(double x)
{
	double rv = 0;	int Socket;
	struct table *dce_table = NULL;

	dce_checkver(2, 0);
	if ((Socket = dce_findserver("a1")) >= 0) {
		dce_push_double(Socket,"x",x);
		dce_table = dce_submit("a1", "sin1", Socket);
	}
	rv = dce_pop_double(dce_table,"dce_result");
	dce_table_destroy(dce_table);
	return(rv);
}
H-файл для него является следующим:
**************************************/
*
* Client Header for a1
* Generated by rpcmake version 3.0
* on Thursday, December 31, 1998 at 19:17:39
*
**************************************/

#ifdef __cplusplus
	extern "C" {
#endif

extern double sin1(double );

#ifdef __cplusplus
	}
#endif

Код клиентского приложения, аналогичный приведенному выше для Delphi, в случае С++Builder выглядит следующим образом:
//-----------------------------------------
#include "dceinc.h"
#include "myserv.h"
USEUNIT("a1_c.c");
USELIB("odet30.lib");
//-----------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
dce_setenv("client.env",NULL,NULL);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormDestroy(TObject *Sender)
{
dce_release();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::BitBtn1Click(TObject *Sender)
{
 int i; double x1,y;
 for (i=1;i<271;i++)
 {
 x1=0.1*float(i);
 y=sin1(x1);
 Chart1->Series[0]->AddXY(x1,y,FloatToStr(x1),clWhite);
 }
}
//-----------------------------------------
В начало

В начало

3.8. Создание клиентского приложения (Visual Basic)

Отметим, что клиентское приложение может быть создано с помощью любых версий и разновидностей Delphi (начиная с 1.0 и включая Standard-версии), любых версий C++Builder и вообще любых компиляторов С++. Помимо этого для создания клиентских приложений можно использовать и другие средства разработки. В качестве примера рассмотрим Visual Basic for Applications. Для начала создадим клиентский stub-код для Visual Basic, для чего произведем и выполним командный файл вида:

set ODEDIR=F:\OPENENV\ENTERA\TCP
PATH=%ODEDIR%\BIN;%PATH%
rpcmake.EXE -d myserv.def -c bas 

В результате получим файл a1_c.vb вида:

Function sin1# (x#)
	dim dce_table as long, Socket as integer

	call dce_checkver(2,0)
	Socket = dce_findserver("a1")
	If (Socket > -1) Then
		Call dce_push_double(Socket,"x",x)
		dce_table = dce_submit("a1","sin1",Socket)
	End If
	sin1 = dce_pop_double(dce_table,"dce_result")
	Call dce_table_destroy(dce_table)
End function

Теперь создадим новый документ MS Word 97 (или MS Excel 97), сделаем видимой панель инструментов Visual Basic, войдем в режим конструктора и выведем на экран панель интерфейсных элементов. Далее поместим в документ кнопку.

Затем дважды щелкнем на созданной кнопке и перейдем в редактор Visual Basic. Добавим к документу форму UserForm1, поместим на ней несколько меток.

Теперь создадим обработчик события, связанный с нажатием на кнопку CommandButton1 в документе (его прототип уже имеется в редакторе кода):

Private Sub CommandButton1_Click()
x = sin1#(0.25)
UserForm1.Label1.Caption = x
x = sin1#(0.5)
UserForm1.Label2.Caption = x
x = sin1#(0.75)
UserForm1.Label3.Caption = x
x = sin1#(1#)
UserForm1.Label4.Caption = x
x = sin1#(1.25)
UserForm1.Label5.Caption = x
x = sin1#(1.5)
UserForm1.Label6.Caption = x
x = sin1#(1.75)
UserForm1.Label7.Caption = x
x = sin1#(2#)
UserForm1.Label8.Caption = x
x = sin1#(2.25)
UserForm1.Label9.Caption = x
x = sin1#(2.5)
UserForm1.Label10.Caption = x
x = sin1#(2.75)
UserForm1.Label11.Caption = x
x = sin1#(3#)
UserForm1.Label12.Caption = x
UserForm1.Show
End Sub

После обработчика события добавим stub-код, содержащийся в сгенерированном файле a1_c.vb.

И, наконец, экспортируем в проект c помощью пункта меню Файл/Экспорт файла модуль odet30.bas из комплекта поставки Entera.Создадим файл client.env в каталоге, содержащем документ. Возможно, потребуется отредактировать присоединенный к проекту модуль, изменив параметры процедуры dce_setenv и указав путь к файлу client.env:

rv = dce_setenv("client.env", "", "")

Отметим, что библиотека odet30.dll должна быть доступна нашему приложению, так как из нее оно производит вызовы функций.Теперь можно вернуться в документ из среды разработки Visual Basic for Applications, выйти из режима конструктора и нажать кнопку в документе. На экране появится форма с результатами вызова удаленных процедур примерно следующего вида.

Напомним, что перед запуском приложения следует убедиться, что брокер и сервер запущены.

В начало

В начало

4. Управление функционированием информационной системы предприятия с помощью Inprise AppCenter

В рассмотренных в предыдущем разделе примерах требовалось запускать Entera Broker и серверы функциональности вручную. При эксплуатации системы, содержащей множество подобных серверов функциональности, выполняющихся под управлением различных платформ, процедура запуска необходимых приложений и наблюдения за их выполнением может оказаться весьма трудоемким процессом. Поэтому в таких системах нередко используются специальные средства управления серверами и наблюдения за ними. Inprise AppCenter представляет собой подобное средство, в значительной степени ориентированное на управление серверами функциональности, созданными с помощью Entera, и брокерами Entera.
В начало

В начало

4.1. Обзор AppCenter

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

AppCenter состоит из пяти компонентов — утилиты просмотра (AppCenter Viewer), агента, монитора, репозитария и брокера.

Таблица 1. Компоненты AppCenter

Компонент Описание
Viewer Пользовательская утилита для конфигурации, контроля и управления приложениями
Agent Компонент, управляющий приложениями, содержащимися на данном компьютере. Должен присутствовать на всех компьютерах, входящих в распределенную систему, и быть запущен прежде, чем начнется управление распределенной системой
Monitor Средство контроля объектов, подлежащих управлению
Repository Централизованное хранилище данных о конфигурациях приложений и состоянии объектов, подлежащих управлению
Broker Сервис, способствующий поиску компонентов AppCenter

Как видно из приведенной выше схемы, репозитарий AppCenter, хранящий сведения о сервисах промежуточного слоя, устанавливается в сети в одном экземпляре (напомним, что такие базы данных нужны в случае, если необходимо инициировать удаленный запуск сервера по запросу клиента). Компонент AppCenter Agent должен быть установлен на всех компьютерах, содержащих подлежащие управлению сервисы (он представляет собой сервис, позволяющий на определенных условиях удаленно запускать те или иные приложения, управляемые данным компьютером; напомним, что подобные сервисы в распределенных системах должны существовать обязательно, хотя бы из соображений элементарной безопасности).

AppCenter Broker также существует в одном экземпляре и предназначен, как и Entera Broker, для поиска в сети сервиса, необходимого для обратившегося клиента (то есть представляет собой Directory Service).

Что касается AppCenter Viewer, то это пользовательская утилита (написанная на Java и, соответственно, выполняемая под управлением разных платформ), позволяющая описывать правила функционирования управляемых сервисов. В сети можно иметь несколько компьютеров, содержащих AppCenter Viewer.

Каким образом происходит взаимодействие сервисов AppCenter c управляемыми сервисами? Прежде всего с помощью генерации брокером AppCenter IP-вызовов с определенной частотой c целью поиска агентов. Замеченные изменения регистрируются в базе данных. Отметим, что брокеры Entera являются по отношению к AppCenter Broker управляемыми приложениями.

В начало

В начало

4.2. Использование AppCente

Порядок запуска приложений AppCenter должен быть следующим:

1. Broker

2. Репозитарий (Database)

3. Агенты

4. Viewer

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

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

В начало

В начало

4.3. Создание и редактирование конфигураций

В качестве простейшего примера создадим конфигурацию, устойчивую к сбоям. С этой целью щелкнем правой клавишей мыши по папке Configurations и из контекстного меню выберем пункт Wizards|New Entera Configuration. Введем для конфигурации имя Sinus.

Далее появится несколько диалоговых окон, в которых следует ввести данные в интерфейсные элементы. В частности, следует зарегистрировать используемые в данной конфигурации компьютеры, указать имена компьютеров, на которых функционируют серверы и брокеры, каталоги, в которых находятся исполняемые файлы серверов функциональности, указать номера TCP-портов для обращения к брокерам, и в результате будут автоматически сгенерированы env-файлы (ранее мы создавали их вручную).

В результате ответов на вопросы будет создана конфигурация из двух серверов функциональности с балансом загрузки.

Выбрав из контекстного меню опцию Properties, можно изменить свойства управляемых объектов (например, число попыток повторного запуска после остановки сервера).

Выбрав закладку Dependencies, можно установить связи между объектами (например, указать, какой брокер Entera обслуживает данный набор серверов).

Выбрав закладку Hosts, можно просмотреть или переопределить связи между компьютерами и серверами.

Теперь можно запустить конфигурацию и пронаблюдать, как поочередно запускаются объекты (в нашем случае исполняемые файлы a1_s.exe). Если это приложение принудительно закрыть, AppCenter будет снова пытаться запустить его, пока не будет достигнуто число попыток, указанное в параметре Weighting.

Можно создать конфигурацию и без использования экспертов, выбирая пункт New из соответствующих контекстных меню и определяя свойства вновь созданных объектов. Есть также возможность создания так называемых DUMMY-конфигураций, то есть конфигураций, не соответствующих никаким реальным объектам, с целью моделирования их поведения. Для имитации их поведения можно создавать макросы AppCenter.

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

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

Отметим, что объекты AppCenter обычно создаются на основе шаблонов с заранее предопределенными свойствами. Однако у серверов функциональности могут быть и собственные характеристики, за которыми необходимо осуществлять наблюдение, например количество или интенсивность RPC-вызовов, объем передаваемых данных. Чтобы наблюдаемые объекты могли предоставлять такие характеристики, они должны содержать экспортирующие их вызовы функций Enterprise Management Interface (EMI) API (обсуждение которого выходит за рамки данной статьи). В этом случае следует создать собственный шаблон управляемого объекта (например, на основе уже имеющегося).

Для собственного шаблона объектов можно определить дополнительные свойства, которые при создании объектов на основе этого шаблона могут быть доступны для редактирования или наблюдения.

В начало

В начало

4.4. Мониторинг объектов

Существует несколько режимов работы AppCenter Viewer. Режим редактирования объектов был рассмотрен нами ранее. Помимо него имеется также режим мониторинга объектов.

Еще один режим (Icon Mode) позволяет отображать Viewer в виде пиктограммы, которая меняет вид и становится движущейся, если произошел сбой в работе какого-либо из управляемых объектов.

Последний из возможных режимов — Cockpit Mode — позволяет различными способами отображать параметры функционирования объектов (такие как число обращений клиентских приложений, время отклика и др.), а также вести журнал событий.

Cockpit (в переводе это слово означает «кабина самолета с приборными панелями») представляет собой набор графических объектов для отображения свойств наблюдаемых объектов. Создается он в режиме редактирования с помощью опции меню Cockpit/New. Методом drag-and-drop на появившуюся пустую форму можно перетаскивать пиктограммы наблюдаемых объектов. Далее из появившейся диалоговой панели можно выбрать тип графика и отображаемое свойство объекта, а также характеристики, специфические для данного способа отображения (высоту графика, цвет, масштаб и др.).

Типичный Cockpit выглядит примерно так.

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

В заключение отметим, что с помощью Inprise AppCenter можно управлять не только серверами или брокерами Entera, но и любыми другими приложениями, если таковые зарегистрированы в его репозитарии.

 

Российское представительство Inprise:

Тел.: 7(095)238-36-11

e-mail: info@inprise.ru

КомпьютерПресс 3'1999