Статьи

Теперь работает на Windows Azure


Я взял несколько выходных из академической исследовательской работы, чтобы расслабиться и поиграть с некоторыми личными интересами, и одним из этих интересов была разработка .NET.
Я работал над несколькими задачами и проектами, о которых вы скоро услышите, но одним из моих планов было вернуться к регулярному ведению блогов и обновить мой блог-движок до чего-то более современного. Частью этого плана было перенести мой блог на решение для облачного хостинга, предпочтительно
Microsoft Windows Azure . Я вел свой блог на выделенном сервере Rackspace, размещенном моим
другом, но я подумал, что наконец-то пришло время попробовать что-то другое!

Старые читатели помнят, что за последние 6 лет я использовал несколько блоговых движков для своего блога, включая различные версии Community Server, Graffiti CMS и, наконец, мой собственный блог-движок, написанный на ASP.NET MVC, Behistun . Я почти два года использую одну и ту же кодовую базу для Behistun с небольшим обновлением с ASP.NET MVC 1.0 до 2.0. Этот период был единственным спокойным временем в моем блоге, так как я регулярно использовал ранние сборки новых технологий и блог-движков. Сначала я думал об использовании блогового движка с открытым исходным кодом или системы управления контентом для своего блога, чтобы уберечь себя от поддержки кода, но, как я напишу позже, в итоге я обновил Behistun и написал все сам.

В наши дни все говорят об облачных вычислениях и переносе приложений в облачные решения, и здесь Windows Azure является одним из основных вариантов для многих разработчиков и компаний. Хотя в действительности нет необходимости вести блог в облаке (по крайней мере, на данный момент), я подумал, что было бы неплохо перенести мой блог в Windows Azure, поскольку я лично был в восторге от этого.

фруктовый сад

Среди существующих движков блогов, работающих на ASP.NET MVC, Orchard представляется наиболее перспективным вариантом, и у него было преимущество в том, что у него был специальный пакет развертывания для Windows Azure, который обслуживал некоторые известные сайты. Поэтому я решил попробовать Orchard и переместить свой блог в эту хорошую систему управления контентом.

Самой большой проблемой могла быть миграция данных, и мне посчастливилось найти хороший модуль BlogML для Orchard . Поскольку у меня была огромная база данных, мне пришлось написать собственное приложение, чтобы экспортировать мои данные в меньшие файлы BlogML и импортировать их в Orchard по одному. Это работало хорошо, но, пытаясь импортировать тему моего блога в Orchard, я столкнулся с трудностями. У Orchard хорошая структура движка тем, но она не соответствовала моим ожиданиям.

Игнорируя эту незначительную проблему, я перешел к развертыванию своего блога Orchard в Windows Azure, но это оказалось большой проблемой, поскольку он не работал должным образом, и не только я не мог заставить Orchard работать так, как мне нужно, но и Я не мог переместить мои статические файлы на новый сервер.

В конце концов, мне пришлось сдаться, хотя я смог продолжать использовать Orchard, но моей главной заботой было обслуживание и будущие обновления. Поэтому я решил поработать над Behistun и посмотреть, смогу ли я переместить его в Windows Azure.

Обновление Behistun для Windows Azure

Первым и наиболее очевидным шагом было обновление кодовой базы Behistun для работы с Windows Azure. Это было достаточно просто выполнить в ближайшее время и иметь развертываемый пакет, который успешно работал в Azure. К счастью, я разработал Behistun с простотой в качестве основной цели, и это помогло в этом процессе.

Было выполнено три больших задания, чтобы можно было перенести мой блог в облако. Сначала мне пришлось перенести статический контент в хранилище Windows Azure. Во-вторых, мне пришлось заменить все старые ссылки на статический контент на новые URI хранилища Windows Azure. В-третьих, мне пришлось перенести базу данных SQL Server с обновленными данными в SQL Azure.

Миграция статического содержимого

Одной из основных проблем для старого блога, такого как мой, является количество статического контента (например, изображений и загружаемых файлов). Поскольку Azure не поддерживает традиционную систему хранения, мне пришлось перенести все эти файлы в Windows Azure Storage. Я написал простое консольное приложение для выполнения этой задачи, которое просматривает подпапки по определенному пути, извлекает имена папок, создает контейнеры в хранилище BLOB-объектов Windows Azure с тем же именем и загружает в них файлы. Код для этой цели представлен ниже:

static void Main(string[] args)
{
string storageFilePath = @"C:\AzureFileUploader\storage.txt";
 
Console.Title = "Blog File Uploader to Windows Azure Storage";
 
try
{
CloudStorageAccount cloudStorageAccount;
CloudBlobClient blobClient;
 
cloudStorageAccount = CloudStorageAccount.DevelopmentStorageAccount;
//cloudStorageAccount = CloudStorageAccount.Parse("DefaultEndpointsProtocol=https;AccountName=<youraccountname>;AccountKey=<youraccountkey>");
 
blobClient = cloudStorageAccount.CreateCloudBlobClient();
 
CloudBlobContainer blobContainer;
BlobContainerPermissions containerPermissions;
CloudBlob blob;
 
blobClient.Timeout = new System.TimeSpan(1, 0, 0);
 
string[] alreadyUploaded = File.ReadAllLines(storageFilePath);
 
string[] directories = Directory.GetDirectories(@"C:\wwwroot\Storage\Images\Posts");
foreach (string directoryName in directories)
{
DirectoryInfo directoryInfo = new DirectoryInfo(directoryName);
 
string containerName = directoryInfo.Name;
 
if (!alreadyUploaded.Contains<string>(containerName))
{
Console.WriteLine(string.Format
("Starting container creation {0}.", containerName));
 
blobContainer = blobClient.GetContainerReference(containerName.ToLower());
 
blobContainer.CreateIfNotExist();
Console.WriteLine(string.Format
("Finished container creation {0}.", containerName));
 
containerPermissions = new BlobContainerPermissions();
 
containerPermissions.PublicAccess = BlobContainerPublicAccessType.Blob;
blobContainer.SetPermissions(containerPermissions);
 
FileInfo[] files = directoryInfo.GetFiles();
foreach (FileInfo file in files)
{
string fileName = file.Name;
string filePath = file.FullName;
 
blob = blobContainer.GetBlobReference(fileName);
 
Console.WriteLine(string.Format("Starting file upload {0}.", fileName));
blob.UploadFile(filePath);
Console.WriteLine(string.Format
("File upload completed to blob {0} - {1}.", fileName, blob.Uri));
}
File.AppendAllLines(storageFilePath, new List<string> { containerName });
Console.WriteLine("***********************************");
}
}
}
catch (StorageClientException e)
{
Console.WriteLine(string.Format("Storage client error: {0}", e.Message));
}
 
catch (Exception e)
{
Console.WriteLine(string.Format("Error: {0}", e.Message));
}
 
Console.ReadLine();
}

Есть несколько моментов об этом коде. У него есть два конструктора для CloudStorageAccountгде один используется с локальной средой тестирования, а другой готов к настройке с производством в хранилище Windows Azure (закомментировано в приведенном выше коде). Другой момент касается пользовательского тайм-аута для больших файлов для конкретных случаев, когда файл может быть большим. Третий пункт — это использование текстового файла для хранения списка контейнеров, которые были обработаны ранее, поэтому в случае исключения я могу начать заново, не переделывая ничего. Я реализовал эту функцию, потому что в моих старых именах папок были исключительные случаи, когда имя папки было длиннее максимально допустимого для имени контейнера или подчеркивалось в имени (что теперь разрешено в именах контейнеров хранилища Windows Azure). Я переименовал эти несколько папок вручную, чтобы решить проблему, а также загрузил некоторые конкретные папки вручную, используяAzure Blob Studio .

Замена ссылок

Загрузив данные, я перешел, заменив ссылки в моей локальной базе данных SQL Server в теле сообщений, чтобы отразить изменения. Это было очень легко, используя LINQ to SQL!

static void Main(string[] args)
{
Console.Title = "Blog Image Reference Replacer";
 
DBLoaderDataContext context = new DBLoaderDataContext();
var posts = from p in context.Posts select p;
 
foreach (Post post in posts)
{
string body = post.Body;
body = body.Replace("http://nayyeri.net/storage/images/posts", "http://keyvan.blob.core.windows.net");
body = body.Replace("http://nayyeri.net/storage/downloads", "http://keyvan.blob.core.windows.net/downloads");
 
post.Body = body;
 
Console.WriteLine("Editing post {0} completed.", post.Title);
 
context.SubmitChanges();
}
 
Console.ReadLine();
}

Перенос данных

Обновив данные в локальном экземпляре SQL Server, я использовал мастер миграции SQL Azure для их экспорта в SQL Azure. Это был также легкий шаг.

Настройка пользовательских доменных имен

Наихудшая часть процесса миграции заключалась в том, что я пытался установить свое собственное доменное имя, чтобы мой блог указывал на мой хостинг-домен Windows Azure. К сожалению, текущие функции, предоставляемые Windows Azure, не позволяют указывать точное доменное имя по адресу Azure, и вам необходим префикс домена (например, www.) Для указания этого домена. Это было немного сложно для меня, так как я был одним из главных сторонников отсутствия www в сообществе .NET и поддерживал такие URL в этом блоге в течение последних шести лет.

В любом случае мне пришлось отказаться от этого интереса, чтобы иметь возможность использовать Windows Azure, поэтому я перенаправил свой основной домен на www.nayyeri.net, который указывал на мой адрес Azure, используя запись CNAME. Я надеюсь, что команда Windows Azure добавит лучшие функции в этой области очень скоро.

Вывод

Мой блог теперь работает на Windows Azure, и это означает, что в будущем я должен ожидать наименьшего времени простоя. В наши дни рано ожидать, что блог будет размещаться в облаке, но я с энтузиазмом делал это, как в старые времена, когда я следил за последними изменениями технологий и платформ. К сожалению, занятие исследованиями и курсами не позволило мне сделать это, так как я приехал в Соединенные Штаты.

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

Я планирую обновить кодовую базу Behistun до ASP.NET MVC 3.0, добавить в ближайшее время некоторые новые функции и развернуть ее в Windows Azure, чтобы воспользоваться всеми функциями, предоставляемыми в облаке. В отличие от того, что я говорил ранее, я не думаю, что я собираюсь делиться исходным кодом Behistun с общественностью, так как в течение последних 1,5 лет мое мнение о написании определенных проектов с открытым исходным кодом изменилось, и я не хочу выпускать открытый исходный движок блога или CMS.