| Воскресенье, 16 июня, 2013
Метки: ASP.NET MVC, Windows Azure Комментарии: 0
Изучая Windows Azure, разработчики наверняка знают, что такое worker-роли и зачем они нужны. Это виртуальные машины, предназначенные для выполнения фоновых вычислений. Но есть небольшая проблема в их использовании в самом начале запуска проекта. Если у приложения небольшое количество пользователей и нагрузка в виде фоновых вычислений низкая, то worker-роль использовать достаточно накладно и излишне. Для чего резервировать целый сервер для редкой и несложной работы? Поэтому использовать уже имеющуюся web-роль, в которой работает само веб-приложение будет разумным решением в самом начале, пока вы не набрали большое количество пользователей.
Worker-роль состоит из класса, который наследуется от RoleEntryPoint. Это выглядит примерно так:
public class WorkerRole : RoleEntryPoint
{
public override bool OnStart()
{
// ...
return base.OnStart();
}
public override void Run()
{
while (true)
{
// ...
}
}
}
Этот же самый код будет работать и в web-роли. Просто добавим этот класс в проект ASP.NET MVC и эта роль будет работать как worker-роль, находясь в виртуальной машине web-роли.
На первых порах это решение поможет сократить ненужные траты, но как только нагрузка на приложение будет возрастать, то класс роли можно перенести в приложение worker-роли и масштабировать приложение по мере его роста.
На данный момент мы имеем зависшее сообщение в очереди и мы знаем как понизить расходы используя worker-роль внутри web-роли. Давайте теперь отправим email. Будем использовать сервис SendGrid, который предоставляет преимущество быстрой разработки. Установим эту библиотеку через Nuget.
После установки библиотеки SendGrid можно написать код, который читает сообщения из очереди и отправляет письма. Ниже код чтения из очереди:
public class WebRole : RoleEntryPoint
{
public override bool OnStart()
{
CloudStorageAccount.SetConfigurationSettingPublisher(
(configName, configSetter) =>
{
string value = "";
if (RoleEnvironment.IsAvailable)
{
value = RoleEnvironment.
GetConfigurationSettingValue(configName);
}
else
{
value = ConfigurationManager.AppSettings[configName];
}
configSetter(value);
});
return base.OnStart();
}
public override void Run()
{
// emailconfirmation очередь
var account = CloudStorageAccount.
FromConfigurationSetting("StorageConnection");
var queueClient = account.CreateCloudQueueClient();
var queue = queueClient.GetQueueReference("emailconfirmation");
queue.CreateIfNotExist();
while (true)
{
var message = queue.GetMessage();
if (message != null)
{
// ...
// отметим, что сообщение обработано
queue.DeleteMessage(message);
}
else
{
Thread.Sleep(TimeSpan.FromSeconds(30));
}
}
}
}
Как можно видеть из кода, чтение из очереди довольно прямолинейно. Аккаунт хранилища используется для получения ссылки на очередь. И дальше идет бесконечный цикл, забирающий сообщения из очереди. Если сообщение получено, то оно обрабатывается, а если очередь пуста, то происходит пауза на 30 секунд, и потом опять происходит попытка чтения сообщения из очереди.
После прочтения сообщения, десериализуем его, и затем отправляем email через SendGrid:
// десериализуем модель var serializer = new JavaScriptSerializer(); var model = serializer.Deserialize(message.AsString); // создаем новый email объект, используя SendGrid var email = SendGrid.GenerateInstance(); email.From = new MailAddress("service@codehint.ru", "Codehint.ru"); email.AddTo(model.Email); email.Subject = "Добро пожаловать на сайт Codehint.ru!"; email.Html = string.Format( " Привет {0},
" + "Добро пожаловать на сайт Codehint.ru!
" + "С наилучшими пожеланиями,
", model.Name); var transportInstance = REST.GetInstance( new NetworkCredential("username", "password")); transportInstance.Deliver(email); // отмечаем, что сообщение обработано queue.DeleteMessage(message);
Codehint.Ru
Одна вещь, которую нужно отметить. Удаляем сообщение из очереди только после того, как оно успешно обработано. Если, например, worker-роль по каким либо причинам выйдет из строя, то сообщение будет оставаться в очереди и обработается новой worker-ролью. Такой способ не дает пропасть сообщениям и дает гарантию, что они будут обработаны.
Copyright © CodeHint.ru 2013-2025 (v2.4.7 - работает на Angular Universal)Калькулятор инвест-портфеля