| Воскресенье, 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-2024 (v2.4.7 - работает на Angular Universal)Калькулятор инвест-портфеля