Многоуровневое приложение .NET, использующее очереди шины обслуживания (Microsoft Azure Service Bus Queues)

Среда Visual Studio 2010 (или 2012) и бесплатный пакет инструментов разработки Microsoft Azure SDK для .NET облегчают создание приложений для платформы Microsoft Azure. Если на вашем ПК нет Visual Studio 2010, то SDK автоматически установит Visual Web Developer 2010 Express –– бесплатную версию для разработки приложений Microsoft Azure. При изложении материала предполагается, что пользователь не имеет опыта работы с Microsoft Azure. После изучения этого руководства вы создадите многоуровневое приложение, которое использует несколько ресурсов Microsoft Azure, исполняемых в локальной среде.

О чем пойдет речь в данном руководстве:

  • Как подготовить компьютер к разработке приложений для Microsoft Azure с помощью разовой загрузки и установки.
  • Как использовать среду Visual Studio для разработки приложений Microsoft Azure.
  • Как создать многоуровневое приложение Microsoft Azure с помощью веб-роли и рабочей роли.
  • Как осуществлять взаимодействие между уровнями с помощью очередей шины обслуживания.

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

Обзор сценария: межролевое взаимодействие

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

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

Шина обслуживания поддерживает обмен промежуточными сообщениями через промежуточные компоненты — очереди и темы. При использовании очередей каждое сообщение, отправленное в очередь, предназначено для одного получателя. Темы поддерживают модель «публикация/подписка»: каждое опубликованное сообщение становится доступным по каждой подписке, зарегистрированной для темы. Каждая подписка логически управляет собственной очередью сообщений. Подписки можно настроить с помощью правил фильтрации, ограничивающих передаваемые в очередь сообщения только теми, которые соответствуют условиям фильтра. В этом примере мы будем использовать очереди шины обслуживания.

По сравнению с прямой системой обмена сообщениями данный механизм взаимодействия имеет ряд преимуществ.

  • Временное разделение. Благодаря асинхронной модели обмена сообщениями производителям и потребителям не нужно присутствовать в сети одновременно. Шина обслуживания надежно хранит сообщения, пока сторона-потребитель не будет готова их получить. В этом случае компоненты распределенного приложения разъединяются либо естественным образом, например для обслуживания, либо при сбое компонента, не оказывая влияния на систему как на целостную структуру. Кроме того, приложение-потребитель можно переводить в онлайновый режим работы только в определенное время суток.
  • Выравнивание нагрузки. Во многих приложениях нагрузка на систему меняется с течением времени, тогда как время обработки, необходимое для каждой единицы работы, — величина постоянная. Размещение производителей и потребителей сообщений в очереди означает, что рабочее приложение нужно подготовить для использования со средней, а не максимальной нагрузкой. По мере изменения входящей нагрузки размер очереди будет увеличиваться либо уменьшаться. Это ведет к прямой экономии средств на использование инфраструктуры, необходимой для обслуживания нагрузки приложения.
  • Балансировка нагрузки. По мере увеличения нагрузки к операции чтения из очереди можно добавлять дополнительные рабочие процессы. Каждый рабочий процесс обрабатывается только одним сообщением. Кроме того, балансировка нагрузки обеспечивает оптимальное использование рабочих компьютеров, даже если их вычислительная мощность различна, поскольку они извлекают сообщения со своей собственной максимальной скоростью. Такая модель называется конкурирующей потребительской моделью.

В следующих разделах мы рассмотрим код для реализации этой архитектуры.

Настройка среды разработки

Прежде чем приступить к разработке приложения Microsoft Azure, необходимо получить инструменты разработки и настроить среду разработки.

Чтобы установить пакет Microsoft Azure SDK для .NET, щелкните указанную ниже кнопку.

Get Tools and SDK

Когда появится запрос на запуск или сохранение файла WindowsAzureSDKForNet.exe, нажмите кнопку Run.

В окне установщика нажмите кнопку Install и продолжите установку.

После завершения установки у вас появятся все необходимые инструменты для разработки. В пакет SDK входят инструменты, позволяющие без труда разрабатывать приложения Microsoft Azure в Visual Studio. Если среда Visual Studio не установлена на вашем ПК, в процессе инсталляции пакета вы получите бесплатную версию Visual Web Developer Express.

Создание учетной записи Microsoft Azure

Откройте веб-браузер и перейдите на веб-сайт https://www.windowsazure.com.

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

Настройка пространства имен шины обслуживания

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

Войдите на портал управления Microsoft Azure.

В левой нижней навигационной панели портала управления щелкните Service Bus, Access Control & Caching.

В левой верхней панели портала управления щелкните узел Service Bus, а затем нажмите кнопку New.

В диалоговом окне Create a new Service Namespace введите название пространства имен, а затем — чтобы убедиться в его уникальности — нажмите кнопку Check Availability.

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

ВАЖНО! Выберите тот же самый регион, который будет использоваться для развертывания приложения. Именно таким образом можно достичь оптимальной производительности.

Щелкните Create Namespace. Система создаст пространство имен службы и активирует его. Возможно, придется подождать несколько минут, в то время как система будет готовить ресурсы для вашей учетной записи.

В основном окне щелкните имя своего пространства имен службы.

В области Properties в правой части найдите запись Default Key.

В записи Default Key щелкните View. Запомните ключ или скопируйте его в буфер обмена.

Создание веб-роли

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

Создание приложения

Запустите Microsoft Visual Studio 2010 или Microsoft Visual Web Developer Express 2010 с правами администратора. Для этого щелкните правой кнопкой мыши Microsoft Visual Studio 2010 (or Microsoft Visual Web Developer Express 2010), а затем выберите пункт Run as administrator. Для функционирования эмулятора вычислений Microsoft Azure, который рассматривался ранее в этом руководстве, требуется запустить Visual Studio с правами администратора.

В Visual Studio в меню File последовательно выберите NewProject.

В области Installed Templates в группе Visual C# щелкните Cloud, а затем — Microsoft Azure Project. Присвойте проекту имя MultiTierApp. Затем нажмите кнопку OK.

В ролях .NET Framework 4 дважды щелкните ASP.NET MVC 3 Web Role.

Наведите указатель мыши на MvcWebRole1 в разделе Microsoft Azure solution, щелкните значок карандаша и переименуйте веб-роль в FrontendWebRole. Затем нажмите кнопку OK.

В списке Select a template выберите Internet Application, а затем нажмите кнопку OK.

В Solution Explorer правой кнопкой мыши щелкните References и выберите командуManage NuGet Packages... или Add Library Package Reference.

В левой части диалогового окна щелкните Online. Выполните поискWindowsAzure.ServiceBus и выберите элемент Microsoft Azure.Service Bus. Затем завершите установку и закройте диалоговое окно.

Обратите внимание, что теперь в окне отображаются необходимые сборки клиентов и добавлено несколько новых файлов кода.

В Solution Explorer правой кнопкой мыши щелкните Models, а затем последовательно выберите AddClass. В поле Name введите имя OnlineOrder.cs. Затем нажмите кнопкуAdd.

Создание веб-кода для веб-роли

В этом разделе вы создадите различные страницы, отображаемые приложением.

В файле OnlineOrder.cs в Visual Studio замените существующее определение пространства имен следующим кодом.

namespace FrontendWebRole.Models { public class OnlineOrder { public string Customer { get; set; } public string Product { get; set; } } }

В Solution Explorer дважды щелкните файл Controllers\HomeController.cs. В начало файла допишите следующие операторы using, чтобы добавить пространство имен для только что созданной модели, а также шину обслуживания.

using FrontendWebRole.Models; using Microsoft.ServiceBus.Messaging; using Microsoft.ServiceBus;

В файле HomeController.cs в Visual Studio замените существующее определение пространства имен следующим кодом. Этот код содержит методы для отправки элементов в очередь.

namespace FrontendWebRole.Controllers { public class HomeController : Controller { public ActionResult Index() { // Simply redirect to Submit, since Submit will serve as the // front page of this application return RedirectToAction("Submit"); } public ActionResult About() { return View(); } // GET: /Home/Submit // Controller method for a view you will create for the submission // form public ActionResult Submit() { // Will put code for displaying queue message count here. return View(); } // POST: /Home/Submit // Controler method for handling submissions from the submission // form [HttpPost] public ActionResult Submit(OnlineOrder order) { if (ModelState.IsValid) { // Will put code for submitting to queue here. return RedirectToAction("Submit"); } else { return View(order); } } } }

Постройте приложение (нажмите клавишу F6).

Теперь нужно создать представление для метода Submit(), созданного ранее. Правой кнопкой мыши щелкните в методе Submit() и выберите команду Add View.

 

Откроется диалоговое окно для создания представления. Установите флажок Create a strongly-typed view. Выберите класс OnlineOrder в раскрывающемся списке Model class и укажите Create в раскрывающемся списке Scaffold template.

Нажмите кнопку Add.

Теперь вы измените отображаемое имя приложения. В Solution Explorer дважды щелкните файл Views\Shared\_Layout.cshtml, чтобы открыть его в редакторе Visual Studio.

Найдите 

My MVC Application

 и замените его 

LITWARE'S Awesome Products

.

И в заключение настройте страницу отправки для включения некоторых сведений об очереди. В Solution Explorer дважды щелкните файл Views\Home\Submit.cshtml, чтобы открыть его в редакторе Visual Studio. Добавьте следующую строку после

Submit

. На данный момент поле ViewBag.MessageCount пусто. Вы заполните его позднее.

Current Number of Orders in Queue Waiting to be Processed: @ViewBag.MessageCount

Итак, вы развернули пользовательский интерфейс. Чтобы запустить приложение и подтвердить его внешний вид, нажмите клавишу F5.

Написание кода для отправки элементов в очередь шины обслуживания

Сейчас вы добавите код для отправки элементов в очередь. Сначала нужно создать класс, который содержит сведения о подключении к очереди шины обслуживания. Затем следует активировать подключение из файла Global.aspx.cs. И наконец, нужно будет обновить код отправки, созданный ранее в файле HomeController.cs, для фактической отправки элементов в очередь шины обслуживания .

В Solution Explorer правой кнопкой мыши щелкните класс FrontendWebRole (именно класс, а не роль). Последовательно выберите AddClass.

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

Теперь вы вставите код, который содержит сведения о подключении и методы для инициализации подключения к очереди шины обслуживания. В QueueConnector.cs вставьте следующий код и введите значения в поля NamespaceIssuerName и IssuerKey. Эти значения можно найти на портале управления.

using System; using System.Collections.Generic; using System.Linq; using System.Web; using Microsoft.ServiceBus.Messaging; using Microsoft.ServiceBus; namespace FrontendWebRole { public static class QueueConnector { // Thread-safe. Recommended that you cache rather than recreating it // on every request. public static QueueClient OrdersQueueClient; // Obtain these values from the Management Portal public const string Namespace = "your service bus namespace"; public const string IssuerName = "issuer name"; public const string IssuerKey = "issuer key"; // The name of your queue public const string QueueName = "OrdersQueue"; public static NamespaceManager CreateNamespaceManager() { // Create the namespace manager which gives you access to // management operations var uri = ServiceBus Environment.CreateServiceUri( "sb", Namespace, String.Empty); var tP = TokenProvider.CreateShared SecretTokenProvider( IssuerName, IssuerKey); return new NamespaceManager(uri, tP); } public static void Initialize() { // Using Http to be friendly with outbound firewalls ServiceBusEnvironment. SystemConnectivity.Mode = ConnectivityMode.Http; // Create the namespace manager which gives you access to // management operations var namespaceManager = CreateNamespaceManager(); // Create the queue if it does not exist already if (!namespaceManager. QueueExists(QueueName)) { namespaceManager. CreateQueue(QueueName); } // Get a client to the queue var messagingFactory = MessagingFactory.Create( namespaceManager.Address, namespaceManager.Settings. TokenProvider); OrdersQueueClient = messaging Factory.CreateQueueClient( "OrdersQueue"); } } }

Теперь нужно проверить возможность вызова метода Initialize. В Solution Explorerдважды щелкните файл Global.asax\Global.asax.cs.

В конец метода Application_Start добавьте следующую строку.

QueueConnector.Initialize();

И наконец, обновите созданный ранее веб-код для отправки элементов в очередь. ВSolution Explorer дважды щелкните файл Controllers\HomeController.cs, созданный ранее.

Чтобы получить количество сообщений для очереди, обновите метод Submit()следующим образом.

public ActionResult Submit() { // Get a Namespace Manager which allows you to perform management and // diagnostic operations on your Service Bus Queues. var namespaceManager = QueueConnector. CreateNamespaceManager(); // Get the queue, and obtain the message count. var queue = namespaceManager. GetQueue(QueueConnector.QueueName); ViewBag.MessageCount = queue.MessageCount; return View(); }

Чтобы отправить сведения о заказе в очередь, обновите метод Submit(OnlineOrder order) следующим образом.

public ActionResult Submit(OnlineOrder order) { if (ModelState.IsValid) { // Create a message from the order var message = new BrokeredMessage(order); // Submit the order QueueConnector.OrdersQueueClient.Send(message); return RedirectToAction("Submit"); } else { return View(order); } }

Теперь приложение можно запустить повторно. Количество сообщений увеличивается во время каждой отправки заказа.

Cloud Configuration Manager

Windows Azure поддерживает набор управляемых API, что позволяет согласовать способы создания экземпляров клиентов служб Windows Azure (например, шины обслуживания) в облачной среде Microsoft. Интерфейсы API позволяют создавать экземпляры клиентов (например, CloudBlobClientQueueClientTopicClient) независимо от места размещения приложения — локально, в облачной среде Microsoft, на веб-сайтах или в постоянной роли виртуальной машины. Эти интерфейсы можно использовать также для получения сведений о конфигурации, необходимых для создания экземпляров клиентов и изменения конфигурации без повторного развертывания вызывающего приложения. API находятся в классе Microsoft.WindowsAzure.Configuration.CloudConfigurationManager. Кроме того, существуют API на стороне клиента.

Строка подключения

Для создания экземпляра клиента (например, шины обслуживания QueueClient) данные конфигурации можно представить в виде строки подключения. На стороне клиента существует метод CreateFromConnectionString(), который создает этот тип клиента с помощью строки подключения. Рассмотрим на примере следующего раздела конфигурации.

<ConfigurationSettings> … <Setting name="Microsoft.ServiceBus.ConnectionString" value="Endpoint=sb://[yourServiceNamespace]. servicebus.windows.net/;SharedSecretIssuer= [issuerName];SharedSecretValue=[yourDefaultKey]" /> </ConfigurationSettings>

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

QueueClient Client; string connectionString = CloudConfigurationManager. GetSetting("Microsoft.ServiceBus.ConnectionString"); var namespaceManager = NamespaceManager. CreateFromConnectionString(connectionString); if (!namespaceManager. QueueExists(QueueName)) { namespaceManager. CreateQueue(QueueName); } // Initialize the connection to Service Bus Queue Client = QueueClient.Create FromConnectionString(connectionString, QueueName);

В коде, приведенном в следующем разделе, используются данные API управления конфигурацией.

Создание рабочей роли

Сейчас вы создадите рабочую роль, которая обрабатывает отправку заказов. В этом примере используется шаблон проекта Visual Studio Worker Role with Service Bus Queue. Сначала вы получите необходимые учетные данные с помощью Server Explorer в Visual Studio.

В строке меню в Visual Studio выберите View, а затем щелкните Server Explorer. В иерархии Server Explorer появится узел Windows Azure Service Bus, как показано на следующем рисунке.

В Server Explorer щелкните правой кнопкой мыши узел Windows Azure Service Bus, затем выберите команду Add New Connection.

В диалоговом окне Add Connection введите название пространства имен службы, имя издателя и ключ издателя. Затем нажмите кнопку OK для подключения.

В Visual Studio, в Solution Explorer, щелкните правой кнопкой мыши папку Roles в узле проекта MultiTierApp.

Последовательно выберите AddNew Worker Role Project. Откроется диалоговое окноAdd New Role Project.

В диалоговом окне Add New Role Project щелкните элемент Worker Role with Service Bus Queue, как показано на следующем рисунке.

В поле Name введите имя проекта OrderProcessingRole. Затем нажмите кнопку Add.

В Server Explorer щелкните правой кнопкой мыши название пространства имен и выберите пункт Properties. В области Properties Visual Studio первая запись содержит строку подключения, заполняемую конечной точкой пространства имен службы с требуемыми учетными данными авторизации. Например, как показано на следующем рисунке. Дважды щелкните ConnectionString, а затем нажмите сочетание клавиш Ctrl+Cдля копирования строки в буфер обмена.

В Solution Explorer щелкните правой кнопкой мыши проект OrderProcessingRole, созданный на шаге 7, и выберите пункт Properties.

На вкладке Settings диалогового окна Properties щелкните в поле Value строкуMicrosoft.ServiceBus.ConnectionString, а затем вставьте значение конечной точки, скопированное на шаге 8.

Создайте класс OnlineOrder, представляющий заказы по мере их обработки из очереди. Можно повторно использовать уже созданный класс. В Solution Explorer щелкните правой кнопкой мыши проект OrderProcessingRole (именно проект, не роль). Последовательно выберите AddExisting Item.

Перейдите к вложенной папке FrontendWebRole\Models и дважды щелкните файлOnlineOrder.cs, чтобы добавить его в этот проект.

Замените значение переменной QueueName в файле WorkerRole.cs с ProcessingQueue на OrdersQueue, как показано в следующем коде.

// The name of your queue const string QueueName = "OrdersQueue";

В начало файла WorkerRole.cs добавьте следующий оператор using.

using FrontendWebRole.Models;

В функции Run() добавьте следующий код в цикл if (receivedMessage != null), расположенный под оператором Trace.

if (receivedMessage != null) { // Process the message Trace.WriteLine ("Processing", receivedMessage.SequenceNumber.ToString()); // Add these two lines of code // View the message as an OnlineOrder OnlineOrder order = received Message.Get&lt;OnlineOrder&gt;(); Trace.WriteLine(order.Customer + ": " + order.Product, "ProcessingMessage"); receivedMessage.Complete(); }

Создание приложения завершено. Теперь можно протестировать приложение, нажав клавишу F5. Обратите внимание, что количество сообщений не увеличивается, поскольку рабочая роль обрабатывает элементы из очереди и помечает их как завершенные. Чтобы просмотреть выходные данные трассировки рабочей роли, обратитесь к пользовательскому интерфейсу эмулятора вычислений Windows Azure. Для этого щелкните правой кнопкой мыши значок эмулятора в области уведомлений и выберите команду Show Compute Emulator UI.

Автор статьи: Владимир Юнев.