Skip to content
July 29, 2012 / ahriman hpc mode

Быстрый старт первого проекта в Windows Azure. Ч.6.

Миграция веб-сайта в Cloud Services.

Давайте рассмотрим следующий сценарий: вы уже развернули ваш веб-сайт (например, стандартный веб-сайт ASP.NET MVC 4, который будет дальше рассматриваться) на Windows Azure Web Sites, однако по прошествии некоторого времени обнаружили, что от веб-сайта требуется дополнительная функциональность – необходимо, чтобы пользователь мог заходить на ваш веб-сайт и загружать изображения в собственную галерею. Подобный сценарий реализуем с помощью одной функциональности веб-сайтов, однако в списке требований также есть условие гибкой масштабируемости вашего веб-сайта. В том случае, если вы используете только Windows Azure Web Sites, вы можете масштабировать ваш веб-сайт только целиком, что является неэффективным решением – скорее всего, основная нагрузка будет приходиться на обработчиков изображений, нежели на пользовательский веб-интерфейс. Миграция веб-сайта в Cloud Services и переосмысление архитектуры с учетом ролевой модели Windows Azure Cloud Services, а также использование Windows Azure Blob Storage и Service Bus Queues поможет создать эффективную реализацию подобного сценария. В данной части цикла вы создадите облачное приложение, которое будет состоять из двух слоёв:

1) Веб-интерфейс, реализованный в виде Web-роли. На главной странице приложения пользователь сможет загружать изображения, а также просматривать уже загруженные изображения. После загрузки изображения Web-роль будет отправлять изображение в хранилище блобов в контейнер блобов, имя которого будет заранее задано для упрощения задачи, после чего класть сообщение, состоящее из ссылки на блоб с изображением в очередь Service Bus.

2) Обработчик изображений, реализованный в виде Worker-роли. Обработчик в бесконечном цикле будет опрашивать очередь Service Bus на наличие сообщений от Web-роли и в том случае, если сообщение в очереди есть, будет забирать его, получать ссылку на блоб с изображением, затем с помощью механизма копирования исходника-блоба создавать новый блоб с таким же изображением и класть его в хранилище блобов.

Часть 1. Настройка Cloud Services на платформе Windows Azure.

Задание 1 – Создание аккаунта хранилища и вычислительного сервиса

1. Откройте в веб-браузере http://windows.azure.com и войдите в систему, используя ваш Windows Live ID, к которому привязан аккаунт Windows Azure (рис. 1).

clip_image002

Рис. 1. Вход на портал управления Windows Azure

2. Создайте новый аккаунт хранилища, в котором будут храниться данные приложения. В меню Windows Azure нажмите New Storage Account (рис. 2).

clip_image004

Рис.2. Создание нового аккаунта хранилища

3. В появившемся диалоговом окне Create a New Storage Account выберите в выпадающем списке Choose a subscription вашу подписку (рис. 3).

clip_image005

Рис. 3. Выбор подписки для размещения аккаунта хранилища

4. В текстовом поле Enter a URL ввведите имя вашего аккаунта хранилища, например, <yourname>gallery, где <yourname> является уникальным именем. Windows Azure использует это значение для создания URL точек входа сервисов аккаунта хранилищ.

Примечание: имя, используемое для аккаунта хранилища, должно соответствовать DNS-имени и стандартам именования DNS. Более того, имя является публично видимым и должно быть уникальным. Портал проверяет доступность, уникальность и соответствие правилам имени. Если имя не пройдёт проверку, будет выведено сообщение об ошибке.

5. Выберите Create or choose an affinity group и нажмите в выпадающем списке Create a new affinity group.

Примечание: новая аффинная группа необходима для размещения сервиса и аккаунта хранилища в одном месте, что обеспечивает высокую пропускную способность и низкую латентность для приложения и данных, которые оно использует.

6. В диалоговом окне Create a New Affinity Group введите в текстовое поле Affinity Group Name имя аффинной группы, выберите расположение (Location) в выпадающем списке и нажмите OK.

7. Вернувшись в диалоговое окно Create a New Storage Account, нажмите Create для создания нового аккаунта хранилища. Подождите окончания процесса инициализации аккаунта и обновления «дерева» Storage Accounts. Обратите внимание, что панель свойств Properties показывает URL, ассоциированный с каждым сервисом в аккаунте хранилища. Запишите публичное имя аккаунта хранилища – первый сегмент URL ваших точек входа.

8. Нажмите кнопку View, расположенную рядом с Primary access key в панели свойств Properties. В диалоговом окне View Storage Access Keys нажмите Copy to Clipboard (рядом с Primary Access Key). Скопированное значение понадобится для конфигурирования приложения.

Примечание: Первичный Primary Access Key и вторичный ключи доступа Secondary Access Key предоставляют общий секретный ключ, который можно использовать для доступа к хранилищу. Вторичный ключ аналогичен первичному и необходим для целей резервирования. Вы можете пересоздать каждый из ключей в случае скомпрометирования одного из них.

9. Создайте вычислительный сервис, который будет выполнять код вашего приложения. На левой панели нажмите Hosted Services и нажмите кнопку New Hosted Service, расположенную в меню (рис. 4).

clip_image007

Рис. 4. Создание нового сервиса

10. В диалоговом окне Create a new Hosted Service выберите вашу подписку из выпадающего списка Choose a subscription.

11. Введите имя сервиса в текстовое поле Enter a name for your service и укажите URL, введя соответствующее значение Enter a URL prefix for your service, например, <yourname>gallery, где <yourname> должно быть уникальным именем. Windows Azure использует это значение для создания URL точек входа в сервис.

Примечание: Если это возможно, используйте одинаковое имя для аккаунта хранилища и сервиса. Однако вы должны будете выбрать другое имя, если одно из них будет недоступно.

Примечание: Портал производит проверку доступности и соответствия правилам имени. Если имя не пройдёт проверку, будет выведено сообщение об ошибке.

clip_image009

12. Выберите в выпадающем списке Create or choose an affinity group аффинную группу, которую вы создали ранее для аккаунта хранилища.

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

13. Укажите Do not Deploy.

Примечание: Несмотря на то, что вы можете создать и развернуть ваше приложение в Windows Azure одной операцией, заполнив секцию Deployment Options, в этой лабораторной вы выполните развертывание в следующем задании.

14. Нажмите OK для создания сервиса и подождите, пока не завершится процесс инициализации.

15. Перейдите на вкладку Service Bus, Access Control & Caching. Перейдите на вкладку Service Bus. Нажмите New (рис. 5).

clip_image011

Рис. 5. Вкладка управления Service Bus

16. В открывшемся диалоговом окне Create a new Service Namespace введите имя вашего Namespace (например, mytestservicebus), выберите регион расположения и нажмите Create Namespace.

17. Выделите созданное пространство имён и нажмите на кнопку View на панели Properties в поле Default Key.

18. Скопируйте из диалогового окна Default Key значения Default Issuer и Default Key.

Сервисы развертывания и хранения настроены; пространство имён Service Bus создано.

Часть 2. Настройка приложения ASP.NET MVC 4.

1. Откройте Visual Studio 2012 RC с правами администратора.

2. Нажмите New Project. Выберите шаблон Web\ASP.NET MVC 4 Web Application (рис. 1). Назовите проект MVC4Gallery. Выберите Internet Application и снимите галочку с опции Create a unit test project. Нажмите OK. Дождитесь создания проекта.

clip_image012

Рис. 1. Список шаблонов веб-проектов в Visual Studio 2012 RC

3. Нажмите правой кнопкой мыши на директории Models. Нажмите Add=>Class. В открывшемся диалоговом окне введите Image.cs и нажмите OK. Замените содержимое файла Image.cs на код, приведённый ниже.

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

namespace MVC4Gallery.Models

{

public class Image

{

public string Title{ get; set; }

public string Link{ get; set; }

}

}

4. Откройте файл Views\Home\Index.cshtml и замените его содержимое на код, приведенный ниже.

<header>

<div class="content-wrapper">

<div class="float-left">

<p class="site-title">

Наш первый сайт-галерея

</div>

</div>

</header>

<div id="body">

<section class="featured">

<div class="content-wrapper">

<form action="/Home/Upload" method="post" enctype="multipart/form-data">

<label for="title">

<label for="FileData">

Файл</label>

<input type="file" id="FileData" name="FileData" /><br />

<input type="submit" value="Сохранить" />

</form>

Ваши изображения после "обработки":

@foreach (var image in ViewData.Model)

{

@image.Title <br />

<img width="100" height="100" src="@image.Link" /><br />

}

</div>

</section>

</div>

5. Откройте файл Controllers\HomeController.cs и замените его содержимое на код, приведенный ниже. Необходимые зависимости и библиотеки будут добавлены в следующем пункте.

using System;

using System.Collections.Generic;

using System.Collections.Specialized;

using System.Web;

using System.Web.Mvc;

using Microsoft.ServiceBus.Messaging;

using Microsoft.WindowsAzure;

using Microsoft.WindowsAzure.StorageClient;

using MVC4Gallery.Models;

namespace MvcApplication1.Controllers

{

public class HomeController : Controller

{

public ActionResult Index()

{

List<Image> images = getBlobs("ourgallery");

return View(images);

}

[HttpPost]

[ActionName("Upload")]

public ActionResult Upload(string author, string title)

{

this.SendBlobToStorage(author);

return RedirectToAction("Index");

}

public void SendBlobToStorage(string author)

{

try

{

HttpPostedFileBase file = Request.Files[0];

CloudBlob blob = getBlobContainer("ourgallery").GetBlobReference(file.FileName);

NameValueCollection metadata = new NameValueCollection();

metadata["title"] = file.FileName;

blob.UploadFromStream(file.InputStream);

BrokeredMessage msg = new BrokeredMessage(blob.Uri.AbsoluteUri);

SendBrokeredMessageToServiceBusQueue(msg);

}

catch (StorageClientException e)

{

Console.WriteLine("Возникла ошибка во время работы с хранилищем: " + e.Message); System.Environment.Exit(1);

}

}

public List<Image> getBlobs(string author)

{

CloudBlobContainer container = getBlobContainer(author);

List<Image> images = new List<Image>();

foreach (CloudBlob blob in container.ListBlobs())

{

blob.FetchAttributes();

Image image = new Image();

image.Link = blob.Uri.AbsoluteUri;

image.Title = blob.Metadata["title"];

images.Add(image);

}

return images;

}

public static CloudBlobContainer getBlobContainer(string userId)

{

var account = CloudStorageAccount.FromConfigurationSetting("storageaccount");

CloudBlobContainer container = account.CreateCloudBlobClient().GetContainerReference(userId);

container.CreateIfNotExist();

var permissions = container.GetPermissions();

permissions.PublicAccess = BlobContainerPublicAccessType.Container;

container.SetPermissions(permissions);

return container;

}

public static void SendBrokeredMessageToServiceBusQueue(BrokeredMessage msg)

{

QueueDescription qd = new QueueDescription("servicebustest");

qd.MaxSizeInMegabytes = 5120;

qd.DefaultMessageTimeToLive = new TimeSpan(0, 1, 0);

string connectionString =

CloudConfigurationManager.GetSetting("Microsoft.ServiceBus.ConnectionString");

QueueClient Client = QueueClient.CreateFromConnectionString(connectionString, "servicebustest");

Client.Send(msg);

}

}

}

6. Нажмите правой кнопкой мыши на директории References. Выберите Add Reference. В открывшемся диалоговом окне (рис. 3) выберите следующие сборки:

Microsoft.WindowsAzure.StorageClient 1.7.0.0

Microsoft.WindowsAzure.Configuration 1.7.0.0

Microsoft.WindowsAzure.ServiceRuntime 1.7.0.0

Microsoft.ServiceBus 1.7.0.0

System.Runtime.Serialization 4.0.0.0

clip_image014

Рис. 3. Выбор сборок для проекта.

7. Откройте файл Global.asax и добавьте в метод Application_Start() код, приведённый ниже.

CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSettingPublisher) =>

{

var connectionString = RoleEnvironment.GetConfigurationSettingValue(configName);

configSettingPublisher(connectionString);

}

);

8. Щелкните правой кнопкой мыши на проекте. Выберите Add Windows Azure Cloud Service Project (рис. 4).

clip_image016

Рис. 4. Добавление облачного проекта в решение

9. Нажмите правой кнопкой мыши на Roles в созданном проекте MVC4Gallery.Azure. Выберите Add. Нажмите New Worker Role Project (рис. 5).

clip_image017

Рис. 5. Добавление проекта для Worker-роли в решение

10. В Windows Azure Tools 1.7 был добавлен новый шаблон Worker-роли, уже сконфигурированный для использования Service Bus. В окне Add New Role Project выберите Worker Role with Service Bus Queue и нажмите Add (рис. 6).

clip_image019

Рис. 6. Добавление проекта Worker-роли, сконфигурированного для использования Service Bus Queue

11. Откройте файл WorkerRole.cs и замените его содержимое на код, приведённый ниже.

using System;

using System.Collections.Specialized;

using System.Diagnostics;

using System.Net;

using System.Threading;

using Microsoft.ServiceBus;

using Microsoft.ServiceBus.Messaging;

using Microsoft.WindowsAzure;

using Microsoft.WindowsAzure.ServiceRuntime;

using Microsoft.WindowsAzure.StorageClient;

namespace WorkerRoleWithSBQueue1

{

public class WorkerRole : RoleEntryPoint

{

// The name of your queue

const string QueueName = "servicebustest";

// QueueClient is thread-safe. Recommended that you cache

// rather than recreating it on every request

QueueClient Client;

bool IsStopped;

public override void Run()

{

while (!IsStopped)

{

try

{

// Получение сообщения

BrokeredMessage receivedMessage = null;

receivedMessage = Client.Receive();

if (receivedMessage != null)

{

// Обработка сообщения. В данном случае изображение получается из блоба, затем возвращается в том же виде, но с другим именем файла.

GetBlobFromStorage("ourgallery", receivedMessage.GetBody<string>());

receivedMessage.Complete();

}

}

catch (MessagingException e)

{

if (!e.IsTransient)

{

Trace.WriteLine(e.Message);

throw;

}

Thread.Sleep(10000);

}

catch (OperationCanceledException e)

{

if (!IsStopped)

{

Trace.WriteLine(e.Message);

throw;

}

}

}

}

public override bool OnStart()

{

CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSettingPublisher) =>

{

var connectionString = RoleEnvironment.GetConfigurationSettingValue(configName);

configSettingPublisher(connectionString);

}

);

// Определение максимального количества одновременных подключений

ServicePointManager.DefaultConnectionLimit = 12;

// Создание очереди в том случае, если ее еще не существует

string sbconnectionString = CloudConfigurationManager.GetSetting("Microsoft.ServiceBus.ConnectionString");

var namespaceManager = NamespaceManager.CreateFromConnectionString(sbconnectionString);

if (!namespaceManager.QueueExists(QueueName))

{

namespaceManager.CreateQueue(QueueName);

}

// Инициализация подключения к очереди Service Bus

Client = QueueClient.CreateFromConnectionString(sbconnectionString, QueueName);

IsStopped = false;

return base.OnStart();

}

public override void OnStop()

{

// Закрытие подключения к очереди Service Bus

IsStopped = true;

Client.Close();

base.OnStop();

}

public void GetBlobFromStorage(string author, string title)

{

try

{

CloudBlob sourceBlob = getBlobContainer("ourgallery").GetBlobReference(title);

CloudBlob newBlob = getBlobContainer("ourgallery").GetBlobReference(title + "small_copy");

newBlob.CopyFromBlob(sourceBlob);

NameValueCollection metadata = new NameValueCollection();

metadata["title"] = title + "small_copy";

}

catch (StorageClientException e)

{

Console.WriteLine("Возникла ошибка: " + e.Message); System.Environment.Exit(1);

}

}

public static CloudBlobContainer getBlobContainer(string userId)

{

var account = CloudStorageAccount.FromConfigurationSetting("storageaccount");

CloudBlobContainer container = account.CreateCloudBlobClient().GetContainerReference(userId);

container.CreateIfNotExist();

return container;

}

}

}

12. Добавьте в проект MVC4Gallery файл WebRole.cs и замените его содержимое на код, приведённый ниже.

using System;

using System.Collections.Generic;

using System.Linq;

using Microsoft.WindowsAzure;

using Microsoft.WindowsAzure.Diagnostics;

using Microsoft.WindowsAzure.ServiceRuntime;

using Microsoft.WindowsAzure.StorageClient;

namespace MVC4Gallery

{

public class WebRole : RoleEntryPoint

{

public override bool OnStart()

{

RoleEnvironment.Changing += RoleEnvironmentChanging;

return base.OnStart();

}

private void RoleEnvironmentChanging(object sender, RoleEnvironmentChangingEventArgs e)

{

if (e.Changes.Any(change => change is RoleEnvironmentConfigurationSettingChange))

{

e.Cancel = true;

}

}

}

}

13. Нажмите два раза правой кнопкой мыши на MVC4Gallery в Roles облачного проекта для того, чтобы открыть графический интерфейс администрирования Web-роли (рис. 7).

clip_image021

Рис. 7. Графический интерфейс управления Web-ролью

14. На вкладке Configuration снимите отметку с опции Enable Diagnostics. Перейдите на вкладку Settings, нажмите Add Setting и создайте новую настройку конфигурации с именем storageaccount. Укажите её тип как Connection String, после чего нажмите на кнопку с троеточием и настройте строку подключения. Необходимые данные были записаны в Части 1. Нажмите Add Setting и введите имя Microsoft.ServiceBus.ConnectionString (тип – String), после чего вставьте в поле Value следующую строку:

Endpoint=sb://[имяпространстваимён].servicebus.windows.net;SharedSecretIssuer=owner;SharedSecretValue=[DefaultKey]

Где наименование пространства имён для части Endpoint, Default Issuer для SharedSecretIssuer и Default Key для SharedSecretValue.

15. Нажмите OK.

16. Нажмите два раза правой кнопкой мыши на WorkerRoleWithSBQueue1 в Roles облачного проекта для того, чтобы открыть графический интерфейс администрирования Worker-роли.

17. На вкладке Configuration снимите отметку с опции Enable Diagnostics. Перейдите на вкладку Settings, нажмите Add Setting и создайте новую настройку конфигурации с именем storageaccount. Укажите её тип как Connection String, после чего нажмите на кнопку с троеточием и настройте строку подключения. Необходимые данные были записаны в Части 1. Нажмите OK.

18. Вставьте необходимые значения в строку подключения для настройки Microsoft.ServiceBus.ConnectionString. Необходимоые данные были записаны в Части 1 – наименование пространства имён для части Endpoint, Default Issuer для SharedSecretIssuer и Default Key для SharedSecretValue.

19. Сохраните изменения и закройте графический интерфейс управления Worker-ролью.

20. Запустите проект, нажав F5. Проект запустится в локальном эмуляторе вычислений и запустит браузер с представлением Home/Index (рис.8).

clip_image023

Рис. 8. Первая страница веб-сайта

21. Выберите изображение и нажмите Сохранить.

22. После загрузки изображения страница обновится (рис. 9).

clip_image025

Рис. 9. Обновлённая страница веб-сайта

23. Обратите внимание, что в данный момент показывается только одно изображение – то, которое вы загрузили. Спустя некоторое время (достаточно нескольких секунд) обновите страницу (рис. 10) – это время понадобится обработчику изображений, чтобы опросить очередь, получить сообщение от Web-роли, загрузить блоб, создать его копию и положить новый блоб в хранилище.

clip_image027

Рис. 10. Обновлённая страница веб-сайта

Часть 3. Развертывание ASP.NET MVC 4 приложения на платформу Windows Azure в Cloud Services из Visual Studio 2012 RC

Для того, чтобы развернуть приложение в Cloud Services на платформу Windows Azure, необходимо соответствующим образом настроить функциональность публикации в Visual Studio 2012 RC.

1) Нажмите правой кнопкой мыши на облачном проекте MVC4Gallery.Azure. Нажмите Publish (рис. 11).

clip_image001

Рис. 11.

2) В открывшемся диалоговом окне раскройте список под Choose your subscription и выберите <Manage…> (рис. 12).

clip_image003

Рис. 12.

3) В открывшемся диалоговом окне Windows Azure Cloud Service Project Management нажмите New.

4) Введите любое удобное вам название нового сертификата, который будет использоваться для развертывания приложения. Нажмите Ok.

5) Нажмите на ссылку Copy the full path. Перейдите на портал управления Windows Azure.

6) Перейдите на вкладку Hosted Services, Storage Accounts & CDN.

7) Перейдите на вкладку Management Certificates.

8) На вкладку Management Certificates нажмите Add Certificate.

9) В открывшемся диалоговом окне Add New Management Certificate нажмите Browse и вставьте в поле Имя файла скопированный из Visual Studio путь к сертификату. Нажмите Открыть. Нажмите Ok.

10) Перейдите на вкладку Hosted Services и скопируйте Subscription ID из панели Properties.

11) Перейдите в Visual Studio 2012 RC.

12) Вставьте скопированный идентификатор подписки в соответствующее поле (рис. 13). Нажмите OK.

clip_image004

Рис. 13.

13) Нажмите Close. Нажмите Next.

14) На странице Windows Azure Publish Settings вы можете настроить дополнительные опции развертывания. Нажмите Publish.

15) Вы можете наблюдать за процессом развёртывания в представлении Windows Azure Activity Log (рис. 14).

clip_image006

Рис. 14. Представление Windows Azure Activity Log

16) Перейдите на портал управления Windows Azure на вкладку Hosted Services. Выберите развернутое приложение и нажмите на ссылку в поле DNS Name на панели Properties, чтобы перейти на веб-сайт (рис. 15).

clip_image008

Рис. 15. Портал управления Windows Azure

17) Обратите внимание, что сайт выглядит так же, как после развёртывания его в локальный эмулятор вычислений. Это связано с тем, что в обоих случаях используется реальное хранилище Windows Azure. Добавьте новое изображение и пронаблюдайте результат.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: