Microsoft Azure CDN 使用 - 自動部署篇
- 2015-04-11
- 13610
- 0
- Microsoft Azure
CDN 內容傳遞網路(Content delivery network)可以有效的利用地理位置加速網站靜態檔案的傳輸,目前市面上有許多公司針對一些常用的元件提供免費的 CDN 服務比如 Microsoft 的 http://www.asp.net/ajax/cdn ,如果把 CDN 的原理用最白話的解釋就是「越近越快」,因為網站的極速是所有網頁開發者所追求的目標,因此即使我們已經把網站全數遷移到 Microsoft Azure 也是建議使用 Microsoft Azure 提供的 CDN 服務讓網站加速的跑起來。
這裡的範例將會使用 Microsoft Azure 的 WebApp 以及使用 ASP.NET MVC 預設範本來做示範。
首先可以看到如果我們選擇了香港的主機靜態檔案的傳輸速度如下
如果讀者朋友有閱讀過雲端的部署建議,應該知道部署於雲端上的靜態檔案並不建議放在網站空間內,會建議改放置為儲存體,因此我們也將範例網站建立一個新的 Blob 空間預備來放置靜態檔案,建立完畢 Blob 空間後就可以將網站中的 Content 和 Scripts 資料夾都往 Blob 丟(本範例將 Images 資料夾建立在 Content 內)

接下來就將是把 Blob 綁到 CDN 上,方式很簡單,建立 CDN 時直接選擇正確的 Blob 路徑即可

CDN 需要散佈到全球各端點,所以剛建立的 CDN 是無法使用的(你直接點選CDN位置會一直得到 404 請耐心等待 CDN 散佈)
CDN 散佈完成後將原本的靜態檔案連結修改為 CDN 位置
<p><img src="~/Content/Image/b.jpg" alt=""/></p>@*原本的位置*@ <p><img src="http://xxxxxx.vo.msecnd.net/static/Content/Image/b.jpg" alt="" /></p>@*改成 CDN*@ <p><img src="~/Content/Image/b2.jpg" alt="" /></p>@*原本的位置*@ <p><img src="http://xxxxxx.vo.msecnd.net/static/Content/Image/b2.jpg" alt="" /></p>@*改成 CDN*@ <p><img src="~/Content/Image/b3.jpg" alt="" /></p>@*原本的位置*@ <p><img src="http://xxxxxx.vo.msecnd.net/static/Content/Image/b3.jpg" alt="" /></p>@*改成 CDN*@
當然這樣的修改在實務上比較不合理,建議讀者可以利用 Helper 的方式來處理,但那並不是本篇文章的重點。
當我們改成使用 CDN 以後立刻可以看出變化,這時候讀者是否就覺得 CDN 的確是好物呢?
(以上的藍箭頭是把靜態檔案放 WebApp 內,而橘色的則是放到 CDN)
但是靜態檔案需要我們自己使用工具往上丟是非常累的,因此推薦各位使用部署時自動部署靜態檔案的技巧,此技巧使用到 Powershell 腳本,此腳本您可以在這裡下載
https://gallery.technet.microsoft.com/scriptcenter/Upload-Content-Files-from-41c2142a
但 demo 調整過此腳本,建議讀者使用 demo 修改過後的版本
<#
.SYNOPSIS
Uploads files from an ASP.NET application project folder (Scripts\ and Content\)
into an Azure storage container.
.EXAMPLE
.\UploadContentToAzureBlobs -ProjectPath "c:\users\<myUserName>\documents"
-StorageContainer "myuserdocuments" -Recurse -CreateStorageContainer
#>
[CmdletBinding(SupportsShouldProcess = $true)]
param(
# The storage account name
[Parameter(Mandatory = $true)]
[string]$StorageAccount,
# The name of the storage container to copy files to.
[Parameter(Mandatory = $true)]
[string]$StorageContainer,
[Parameter(Mandatory = $true)]
[string]$ProjectPath
)
function Get-ScriptDirectory
{
$Invocation = (Get-Variable MyInvocation -Scope 1).Value
Split-Path $Invocation.MyCommand.Path
}
# The script has been tested on Powershell 3.0
Set-StrictMode -Version 3
# Following modifies the Write-Verbose behavior to turn the messages on globally for this session
$VerbosePreference = "ContinueSilently"
Import-Module "C:\Program Files (x86)\Microsoft SDKs\Azure\PowerShell\ServiceManagement\Azure\Azure.psd1" -ErrorAction Stop
Write-Warning "部署至 Blob =>=>=>=>"
# Get a list of files from the project folder
$files = (ls -Path $ProjectPath\Content -File -Recurse) + (ls -Path $ProjectPath\Scripts -File -Recurse)
$context = New-AzureStorageContext `
-StorageAccountName $StorageAccount `
-StorageAccountKey (Get-AzureStorageKey $StorageAccount).Primary
if ($files -ne $null -and $files.Count -gt 0)
{
# Create the storage container.
$existingContainer = Get-AzureStorageContainer -Context $context |
Where-Object { $_.Name -like $StorageContainer }
if (-not $existingContainer -and
$PSCmdlet.ShouldProcess($StorageContainer, "Create Container"))
{
$newContainer = New-AzureStorageContainer `
-Context $context `
-Name $StorageContainer `
-Permission Blob
"Storage container '" + $newContainer.Name + "' created."
}
# Upload the files to storage container.
$fileCount = $files.Count
$time = [DateTime]::UtcNow
if ($files.Count -gt 0)
{
foreach ($file in $files)
{
$blobFileName = (Resolve-Path $file.FullName.Replace("\obj\Release\Package\PackageTmp","") -Relative).Replace(".\","")
$contentType = switch ([System.IO.Path]::GetExtension($file))
{
".png" {"image/png"}
".css" {"text/css"}
".js" {"text/javascript"}
".jpg" {"image/jpeg"}
default {"application/octet-stream"}
}
Set-AzureStorageBlobContent `
-Container $StorageContainer `
-Context $context `
-File $file.FullName `
-Blob $blobFileName `
-Properties @{ContentType=$contentType; CacheControl="public, max-age=86400"} `
-Force
}
}
$duration = [DateTime]::UtcNow - $time
"Uploaded " + $files.Count + " files to blob container '" + $StorageContainer + "'."
"Total upload time: " + $duration.TotalMinutes + " minutes."
}
else
{
Write-Warning "No files found."
}
當然這個 Powershell 不是手動執行,請開啟雲端的發行設定檔

增加以下的CODE
<Target Name="CustomExlucdeFiles" BeforeTargets="ExcludeFilesFromPackage"> <Exec Command="PowerShell -NoProfile -c $(OutDir)..\UploadContentToAzureBlobs.ps1 -StorageAccount 'CDN帳號' -StorageContainer '資料夾名稱本範例是static' -ProjectPath '$(OutDir)..\obj\Release\Package\PackageTmp'" IgnoreExitCode="true"> </Exec> </Target>
如果一切設定正確在執行「發行」動作時可以看到「輸出」視窗會有顯示

這樣的設定就可以讓每次執行「發行」的同時自動將靜態檔案部署至指定的 Blob 中,一切自動化,但你要付出的是每次的部署會變慢。













回應討論