Microsoft Azure CDN 使用 - 自動部署篇
- 2015-04-11
- 11716
- 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 中,一切自動化,但你要付出的是每次的部署會變慢。
回應討論