Все мы с вами прекрасно знакомы с предназначением такой технологии как CDN. Согласно определению из Википедии Content Delivery Network – это географически распределенная сетевая инфраструктура, позволяющая оптимизировать доставку и дистрибуцию контента конечным пользователям в сети Интернет. Сегодня я начинаю серию постов, посвященных CDN от Microsoft. В одной из моих предыдущих публикаций я кратко упоминал о возможности использования Windows Azure CDN для получения различного статического содержимого из хранилища блобов; сегодня же мы с вами подробнее познакомимся с тем как и при помощи каких средств это можно сделать.
В качестве примера, использующего CDN будет продемонстрировано простое Web-приложение с единственной страничкой, содержащей таблицу стилей и движок JQuery. Для начала весь статический контент будет храниться на сервере рядом с приложением, в дальнейшем мы перенесем его в хранилище блобов и в конце концов получим доступ к нему посредством Azure CDN.
Итак, в первую очередь создадим стандартную заготовку ASP.NET MVC 3 приложения и слегка подредактируем вьюшку, которая используется на главной странице. Давайте посмотрим на код представления
Как видим я воспользовался extension-методом StaticContent для получения ссылок на статическое содержимое и для упрощения генерации урлов, в дальнейшем это очень пригодится. Сам код расширяющего метода представлен листингом ниже.
На данный момент вся статика находится на нашем сервере. Но мы хотим получать ее из облака. Для загрузки контента в хранилище блобов я воспользовался командлетом PowerShell, свободно распространяемом в Интернете. Командлет поставляется совместно с конфигурационным файлом, в котором необходимо прописать идентификатор подписки, имя storage-аккаунта, ключ доступа к хранилищу, название целевого контейнера и путь к исходной папке, в которой хранятся загружаемые файлы. Для наглядности давайте посмотрим на этот файл.
Если Вы знакомы с PowerShell сам командлет также ничем особенным не удивит. Вот его код.
Как только файлы будут успешно загружены, незначительно изменим код нашего расширяющего метода, а именно перенаправим все ссылки на хранилище блобов вместо локального сервера.
После запуска убедимся в том, что сайт все также успешно подгружает статику, но уже из хранилища блобов.
На данный момент мы переместили все статическое содержимое в удаленное хранилище , но цель перед нами стояла получать доступ к файлам посредством Windows Azure CDN. Для этого необходимо выполнить следующую последовательность шагов. В первую очередь необходимо активировать точку доступа, делается это в разделе CDN.
В открывшемся модальном окне необходимо выбрать аккаунт в том случае если у нас их несколько и нажать кнопку ОК (при этом не забыть оставить включенной галочку Enable CDN).
После этого нас грозно предупредят о том, что изменения вступят в силу в течение 60 минут. Подождем пока точка перейдет в статус Enabled и скопируем полученный адрес из панельки свойств CDN.
Когда все подготовительные процедуры будут завершены можно снова вернуться к коду приложения и снова изменить тело нашего расширяющего метода. В этот раз мы заменим домен хранилища блобов на CDN-домен.
Если к этому моменту наши изменения распространились по всему миру )) то мы получим контент с ближайшего CDN-узла, иначе придется немного подождать. В завершение продемонстрирую результат выполнения утилиты tracert для домена источника данных и для CDN-домена.
В качестве примера, использующего CDN будет продемонстрировано простое Web-приложение с единственной страничкой, содержащей таблицу стилей и движок JQuery. Для начала весь статический контент будет храниться на сервере рядом с приложением, в дальнейшем мы перенесем его в хранилище блобов и в конце концов получим доступ к нему посредством Azure CDN.
Итак, в первую очередь создадим стандартную заготовку ASP.NET MVC 3 приложения и слегка подредактируем вьюшку, которая используется на главной странице. Давайте посмотрим на код представления
@using MvcApplication1.Models @{ ViewBag.Title = "Home Page"; } @section Header { <link rel="Stylesheet" href="@Url.StaticContent("/content/site.css")" /> <script type="text/javascript" src="@Url.StaticContent("/content/jquery-1.5.1.min.js")"></script> } <h2>@ViewBag.Message</h2> <p> To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>. </p>
Как видим я воспользовался extension-методом StaticContent для получения ссылок на статическое содержимое и для упрощения генерации урлов, в дальнейшем это очень пригодится. Сам код расширяющего метода представлен листингом ниже.
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.WebPages.Html; using System.Web.Mvc; namespace MvcApplication1.Models { public static class UrlHelperExtensions { public static string StaticContent(this UrlHelper helper, string resource) { return helper.Content(resource); } } }
На данный момент вся статика находится на нашем сервере. Но мы хотим получать ее из облака. Для загрузки контента в хранилище блобов я воспользовался командлетом PowerShell, свободно распространяемом в Интернете. Командлет поставляется совместно с конфигурационным файлом, в котором необходимо прописать идентификатор подписки, имя storage-аккаунта, ключ доступа к хранилищу, название целевого контейнера и путь к исходной папке, в которой хранятся загружаемые файлы. Для наглядности давайте посмотрим на этот файл.
Если Вы знакомы с PowerShell сам командлет также ничем особенным не удивит. Вот его код.
function UploadBlobs($container, $directory, $virtualPath) { Write-Output "Uploading $directory files..." Foreach ($file in Get-ChildItem $directory) { if($file.PSIsContainer) { UploadBlobs $container $file.fullname ($virtualPath + $file.name + '/') } else { Write-Output "Uploading $file" $blob = $container.GetBlobReference($virtualPath + $file.name) $blob.Properties.ContentType = GetContentTypeFromExtension $file.extension $blob.Properties.CacheControl = "public, max-age=86400" $blob.UploadFile($file.fullName) } } } function SetCacheControlNoCache($container, $resource) { $blob = $container.GetBlobReference($resource) $blob.Properties.CacheControl = "public, max-age=0"; $blob.SetProperties() } function GetContentTypeFromExtension([string]$extension) { switch ($extension) { ".png" { return "image/png" } ".htm" { return "text/html" } ".pfx" { return "application/x-pkcs12" } ".xml" { return "text/xml" } ".css" { return "text/css" } ".jpg" { return "image/jpeg" } ".jpeg" { return "image/jpeg" } ".bmp" { return "image/bmp" } ".js" { return "text/x-javascript" } ".zip" { return "application/zip" } } Write-Output "application/octet-stream" } $scriptDir = (split-path $myinvocation.mycommand.path -parent) Set-Location $scriptDir $sdkPath = resolve-path "$Env:ProgramFiles\Windows Azure SDK\v1.?\ref" write-host $sdkPath if ($sdkPath -is [Array]) { $refFolder = $sdkPath[-1] } else {$refFolder = [string]$sdkPath} [Reflection.Assembly]::LoadFile($refFolder + ‘\Microsoft.WindowsAzure.StorageClient.dll’) [xml] $xml = get-Content "./configuration.xml" $subId = $xml.settings.subscriptionId $storageAccount = $xml.settings.storageAccount.name $storageAccountKey = $xml.settings.storageAccount.key $containerName = $xml.settings.containerName $sourceFolder = $xml.settings.sourceFolder Write-Host "Uploading files..." $credentials = New-Object Microsoft.WindowsAzure.StorageCredentialsAccountAndKey -ArgumentList $storageAccount, $storageAccountKey $account = New-Object Microsoft.WindowsAzure.CloudStorageAccount -ArgumentList $credentials, TRUE $client = [Microsoft.WindowsAzure.StorageClient.CloudStorageAccountStorageClientExtensions]::CreateCloudBlobClient($account) $timeout = New-Object System.TimeSpan -ArgumentList 0, 10, 0 #set the timeout to 5 minutes. this allows us to upload large blobs. $client.Timeout = $timeout $container = $client.GetContainerReference($containerName) $container.CreateIfNotExist() # set public permissions, only if necessary $publicPermission = New-Object Microsoft.WindowsAzure.StorageClient.BlobContainerPermissions $publicPermission.PublicAccess = [Microsoft.WindowsAzure.StorageClient.BlobContainerPublicAccessType]::Blob $container.SetPermissions($publicPermission) UploadBlobs $container $sourceFolder '' SetCacheControlNoCache $container "images/Destination.jpg" Write-Host "Done!"
Как только файлы будут успешно загружены, незначительно изменим код нашего расширяющего метода, а именно перенаправим все ссылки на хранилище блобов вместо локального сервера.
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.WebPages.Html; using System.Web.Mvc; namespace MvcApplication1.Models { public static class UrlHelperExtensions { public static string StaticContent(this UrlHelper helper, string resource) { return helper.Content(String.Format("https://feschenkoalex.blob.core.windows.net{0}", resource)); } } }
После запуска убедимся в том, что сайт все также успешно подгружает статику, но уже из хранилища блобов.
На данный момент мы переместили все статическое содержимое в удаленное хранилище , но цель перед нами стояла получать доступ к файлам посредством Windows Azure CDN. Для этого необходимо выполнить следующую последовательность шагов. В первую очередь необходимо активировать точку доступа, делается это в разделе CDN.
В открывшемся модальном окне необходимо выбрать аккаунт в том случае если у нас их несколько и нажать кнопку ОК (при этом не забыть оставить включенной галочку Enable CDN).
После этого нас грозно предупредят о том, что изменения вступят в силу в течение 60 минут. Подождем пока точка перейдет в статус Enabled и скопируем полученный адрес из панельки свойств CDN.
Когда все подготовительные процедуры будут завершены можно снова вернуться к коду приложения и снова изменить тело нашего расширяющего метода. В этот раз мы заменим домен хранилища блобов на CDN-домен.
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.WebPages.Html; using System.Web.Mvc; namespace MvcApplication1.Models { public static class UrlHelperExtensions { public static string StaticContent(this UrlHelper helper, string resource) { return helper.Content(String.Format("https://az32162.vo.msecnd.net{0}", resource)); } } }
Если к этому моменту наши изменения распространились по всему миру )) то мы получим контент с ближайшего CDN-узла, иначе придется немного подождать. В завершение продемонстрирую результат выполнения утилиты tracert для домена источника данных и для CDN-домена.
Как видим количество задействованных сетевых устройств в случае использования CDN значительно сокращается, что позволяет получать контент значительно быстрее.
Комментариев нет:
Отправить комментарий