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





Комментариев нет:
Отправить комментарий