Я взял несколько выходных из академической исследовательской работы, чтобы расслабиться и поиграть с некоторыми личными интересами, и одним из этих интересов была разработка .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.