ПКРПСиБД LAB7 Степная Е. В. (548535)
Текст из файла
Национальный исследовательский университет
«Московский Энергетический Институт»
Институт автоматики и вычислительной техники
Кафедра прикладной математики
Лабораторная работа №7
По дисциплине «Проектирование крупных программных систем и баз данных»
На тему «Разработка приложения с событийно-управляемой архитектурой с применением NServiceBus»
Выполнила студентка
Группы А-13-08
Степная Е.В.
Проверил
Куриленко И.Е.
Москва, 2012
Цель работы
Научиться разрабатывать событийно-управляемые приложения на примере использования NServiceBus.
Теория
NServiceBus – популярный фреймворк для интеграции сервисов и разработки распределённых приложений (автор UdiDahan), использующий для транспорта сообщений службы очереди сообщений Microsoft (MicrosoftMessageQueuingServices, MSMQ), которые обеспечивают транзакцион-ность и надёжность пересылки сообщений.
NServiceBus-шина является виртуальной сущностью, полученной в результате взаимодействия всех сервисов вместе. То есть, в каждом процессе присутствует своя сущность шина, обеспечивающая отправку и получение сообщений.
NServiceBus поддерживает несколько шаблонов обмена сообщениями:
• Однонаправленное сообщение (One-way)
• Запрос/ответ (RPC)
• Дуплексный обмен (Full-duplex)
• Издатель/подписчик (Pub/Sub)
Последний шаблон является сильной стороной NServiceBus.
Для NServiceBus является типичным следующее взаимодействие:
Клиентское приложение отправляет на сервис некоторую команду. На сервере происходит ее обработка и, в случае успешного выполнения, сервис публикует сообщение о соответствующем событии, на которое уже подписаны другие сервисы. Клиентское приложение получает статус операции.
Пример. Приход клиента в банк за получением кредита.
Цикл обработки сообщений в NServiceBus:
Пример реализации
Starter.cs
using MyServer.Scheduling;
namespace MyServer
{
using System;
using System.Collections.Concurrent;
using DeferedProcessing;
using NServiceBus;
using PerformanceTest;
using Saga;
class Starter:IWantToRunAtStartup
{
public IBus Bus { get; set; }
public void Run()
{
Console.WriteLine("Press 'S' to start the saga");
Console.WriteLine("Press 'T' to start the saga in multi tenant mode");
Console.WriteLine("Press 'D' to defer a message 10 seconds");
Console.WriteLine("Press 'R' to schedule a task");
Console.WriteLine("To exit, press Ctrl + C");
string cmd;
while ((cmd = Console.ReadKey().Key.ToString().ToLower()) != "q")
{
switch (cmd)
{
case "s":
StartSaga();
break;
case "t":
//make sure that the database exists!
StartSaga("MyApp.Tenants.Acme");
break;
case "d":
DeferMessage();
break;
case "r":
ScheduleTask();
break;
case "p":
PerformanceTest();
break;
}
}
}
void PerformanceTest()
{
var total = 40000;
PerformanceTestMessageHandler.receivedMessages = new ConcurrentBag
PerformanceTestMessageHandler.NumExpectedMessages = total;
PerformanceTestMessageHandler.TimeStarted = DateTime.UtcNow;
System.Threading.Tasks.Parallel.For(0, total, _ => Bus.Defer(TimeSpan.FromMinutes(20), new PerformanceTestMessage()));
}
void DeferMessage()
{
Console.WriteLine(string.Format("{0} - {1}", DateTime.Now.ToLongTimeString(), "Sending a message to be processed at a later time"));
Bus.SendLocal(new DeferredMessage
{
ProcessAt = DateTime.Now.AddSeconds(10)
});
}
void StartSaga(string tenant = "")
{
var message = new StartSagaMessage
{
OrderId = Guid.NewGuid()
};
if (!string.IsNullOrEmpty(tenant))
message.SetHeader("tenant", tenant);
Bus.SendLocal(message);
Console.WriteLine(string.Format("{0} - {1}", DateTime.Now.ToLongTimeString(), "Saga start message sent"));
}
void ScheduleTask()
{
// The actual scheduling is done in ScheduleATaskHandler
Bus.SendLocal(new ScheduleATask());
}
public void Stop()
{
}
}
}
EndpointConfig.cs
namespace MyServer
{
using NServiceBus;
using NServiceBus.Config;
using NServiceBus.MessageMutator;
using NServiceBus.Unicast.Transport;
public class EndpointConfig : IConfigureThisEndpoint, AsA_Server,IWantCustomInitialization
{
public void Init()
{
Configure.With()
.DefaultBuilder()
//shows multi tenant operations of the sagas
.MessageToDatabaseMappingConvention(context =>
{
if (context.Headers.ContainsKey("tenant"))
return context.Headers["tenant"];
return string.Empty;
});
}
}
///
/// This mutator makes sure that the tenant id is propagated to all outgoing messages
///
public class TenantPropagatingMutator : IMutateOutgoingTransportMessages, INeedInitialization
{
public IBus Bus { get; set; }
public void MutateOutgoing(object[] messages, TransportMessage transportMessage)
{
if (Bus.CurrentMessageContext == null)
return;
if (!Bus.CurrentMessageContext.Headers.ContainsKey("tenant"))
return;
transportMessage.Headers["tenant"] = Bus.CurrentMessageContext.Headers["tenant"];
}
public void Init()
{
Configure.Instance.Configurer.ConfigureComponent
DependencyLifecycle.InstancePerCall);
}
}
}
App.config
Литература
Документация NServiceBus.
Характеристики
Тип файла документ
Документы такого типа открываются такими программами, как Microsoft Office Word на компьютерах Windows, Apple Pages на компьютерах Mac, Open Office - бесплатная альтернатива на различных платформах, в том числе Linux. Наиболее простым и современным решением будут Google документы, так как открываются онлайн без скачивания прямо в браузере на любой платформе. Существуют российские качественные аналоги, например от Яндекса.
Будьте внимательны на мобильных устройствах, так как там используются упрощённый функционал даже в официальном приложении от Microsoft, поэтому для просмотра скачивайте PDF-версию. А если нужно редактировать файл, то используйте оригинальный файл.
Файлы такого типа обычно разбиты на страницы, а текст может быть форматированным (жирный, курсив, выбор шрифта, таблицы и т.п.), а также в него можно добавлять изображения. Формат идеально подходит для рефератов, докладов и РПЗ курсовых проектов, которые необходимо распечатать. Кстати перед печатью также сохраняйте файл в PDF, так как принтер может начудить со шрифтами.