- •Лабораторные работы по специальному курсу
- •Лабораторная работа №1. Разработка централизованного алгоритма балансировки распределенного приложения
- •Описание централизованного алгоритма балансировки
- •Оценка загрузки
- •Инициализация балансировки загрузки
- •Принятие решений в процессе балансировки
- •Перемещение объектов
- •Использование .Net Remoting
- •Терминология .Net Remoting
- •Сериализуемый (ByValue - по значению)
- •Форматер
- •Принципы работы с каналами/форматерами
- •Создание объекта с возможностью удаленного доступа
- •Создание сервера
- •Создание клиента
- •Отчётность:
- •Лабораторная работа №2 Разработка и реализация централизованного алгоритма балансировки для вс с произвольной топологией
- •Централизованный алгоритм балансировки приведен в предыдущей лабораторной работе
- •Служба очередей сообщений
- •Настройка msmq
- •Создание очередей
- •Доступ к очередям
- •Удаление очередей
- •Посылка сообщения
- •Чтение сообщений очереди
- •Удаление сообщений из очереди
- •Рекомендуемые программные средства и литература
- •Отчётность:
Создание клиента
Теперь, когда сервер установлен нам требуется создать клиента. Создание объекта Order является точно таким же процессом, что и создание локального объекта, за исключением того, что среда выполнения удаленного доступа перехватывает запрос на создание объекта и возвращает прокси-объект, который и используется клиентом. С точки зрения разработки разработчик может интерпретировать прокси-объект точно так же, как и нормальный экземпляр объекта:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Remoting;
namespace Client
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Клиент создан в {0} на {1}",
DateTime.Now.ToLongTimeString(),Environment.MachineName);
RemotingConfiguration.Configure("client.exe.config");
Order.Order o = new Order.Order();
Console.WriteLine(o.GetMachineName());
Console.WriteLine("Итоговая стоимость: {0}",
o.CalculateItem(12.48,2));
Console.ReadLine();
}
}
}
Чтобы откомпилировать эти приложение, мы должны создать ссылки на объект среды выполнения удаленного доступа и Order.dll. Может показаться странным, что нам требуется ссылка на Order.dll, так как объект исполняется исключительно на сервере. Клиенту, чтобы он мог осуществлять вызов серверного объекта, требуются метаданные из объекта удаленного доступа. Без этих метаданных компилятор и среда выполнения не будут иметь ни малейшего представления, что представляет из себя объект удаленного доступа. Мы также можем получить метаданные с помощью инструмента soapsuds.exe. Для краткости мы будем хранить экземпляр Order.dll на стороне клиента. За дополнительной информацией по вопросам о метаданных обратитесь к документации по .NET SDK и, в частности, по инструменту командной строки soapsuds.exe.
Точно так же, как и на сервере, клиент реализует настроечный файл для получения конфигурации своего объекта удаленного доступа. Файл называется client.exe.config и хранится в той же директории, что и клиентское приложение:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.runtime.remoting>
<application>
<client>
<wellknown type="Order, Order" url="http://mobil185:8080/Order.soap"/>
</client>
</application>
</system.runtime.remoting>
</configuration>
Использование волнового алгоритма
При передаче сообщений (передача сообщений о загрузке компьютера) в сети с определенной топологией следует воспользоваться волновыми алгоритмами. В нашем случае топология сети – неориентированное дерево. Рекомендуется использовать алгоритм «Эхо», который приводится ниже.
Алгортм «Эхо»
Алгоритм «Эхо» может работать для любой топологии распределенной системы. Как и предыдущий алгоритм, в нем имеется один инициатор.
Алгоритм использует метод прохода по графу, называемый «поиск (или просмотр графа) в ширину», описанный, в частности, в учебнике Л.Н.Королева, А.И.Микова «Информатика. Введение в компьютерные науки» для поиска множества R достижимых вершин из данной вершины start.
Метод состоит в том, чтобы продвигаться от начальной вершины по ширине всего фронта, включив сначала в множество R все вершины, смежные с вершиной start, затем смежные со смежными и так далее. В описанном ниже методе Expand(R) расширения множества R множество Out(R) – это множество всех вершин, смежных с вершинами из R, так сказать, достижимых за один шаг. В частности, может оказаться, что все они уже принадлежат R и тогда дальнейшее расширение невозможно. На этом процесс прекращается.
Expand(R):
begin
if Out(R) Ë R then
begin Out(R) Þ R;
Expand(R)
end
end;
Первый вызов – Expand(Out(start)); Предполагается, что Out(Æ) = Æ , Æ Í Æ.
В алгоритме «Эхо» инициатор посылает маркеры всем своим соседям. Любой сайт s (не инициатор), получивший первый раз маркер от одного из своих соседей (обозначим этого соседа pre), рассылает маркеры всем соседним сайтам, кроме того, от которого получил маркер. Соседи поступают точно так же. Волна удаляется от инициатора.
Дальнейший процесс рассмотрим на примере дерева. Волна доходит до некоторых из висячих вершин. Висячей вершине отправлять маркер дальше некуда. Тогда она возвращает его той вершине, от которой получила (вот оно «эхо»). Вершины, получившие «эхо» от своих соседей, возвращают маркеры своим вершинам pre. Те, в свою очередь, генерируют «эхо» своим предшественникам. Наконец «эхо» доходит до инициатора. Инициатор, получив «эхо» от всех своих соседей, выполняет процедуру return(OK).
Ниже приведен распределенный алгоритм, состоящий из описаний процесса вычислений для сайта – инициатора и описаний процессов для сайтов – не-нициаторов. В тексте описания процесса тот сайт, на котором этот процесс выполняется (свой сайт), обозначен идентификатором this (в традициях языка Симула-67). Множество Out(this) – это множество сайтов, смежных по выходу с сайтом this, т.е. тех сайтов, на которые с сайта this можно отправить сообщения по однонаправленным или двунаправленным каналам связи. Функция card( ) задает число кардинальности (мощность) множества, являющегося аргументом этой функции. Переменные, встречающиеся в текстах процессов – локальные (по экземпляру для каждого процесса): обмен информацией между процессами происходит только посредством сообщений, разделяемые переменные отсутствуют. Начальные значения счетчиков counter равны 0.
Процесс для инициатора:
begin for u Out(this) do out token to u ;
while counter < card(Out(this)) do
begin receive token; counter := counter + 1 end ;
return(OK)
end ;
Процессы для не-инициаторов:
begin receive token from u ; pre(this) := u ; counter := counter + 1 ;
for (u Out(this))&(u pre(this)) do out token to u ;
while counter < card(Out(this)) do
begin receive token; counter := counter + 1 end ;
out token to pre(this)
end
