2012年12月20日

[Azure]Auto-Scaling Application Block (1) – Configure AutoScaling Application Block

這裡我會先使用Auto-Scaling Application block來做,其實照著這一篇MSDN做其實還是相當簡單。

Auto-Scaling AB的概念是利用一隻程式去分析想要Scale的Cloud Service Role的Performance資料,當符合某些條件時,就動態的修改Role Instance數目。因此,除了必須要config Auto-Scaling AB外,目標的Cloud Service Role也必須要啟動收集Performance Counter才行。

首先,建立一個Worker Role,然後用Nuget加入Auto-Scaling Application Block。

image

image

進入project setting,確定target framework是.Net Framework 4.0

image

在WorkRole: OnStart()中呼叫AutoScaler的Start(),這樣就寫完程式了。

image

複雜的地方是要怎麼設定。

首先,手動加入兩個XML檔案 : rules.xml與services.xml,並且將他們的copy local設為true。

image

接著要開始config app.config

image

新增一個Autoscaling setting

image

打開Data Point設定

image

在這邊填上Storage相關設定,這裡所指定的Storage,是當Auto-Scaling AB啟動時,會定時將performance資料寫入的位置,Auto-Scaling AB會從這裡的資料決定是否有符合稍後我們設定的rule。

image

為了方便,我們全部都用Local File來儲存Service與Rule資料。

image

選擇剛剛產生的rule.xml

image

同樣的,使用Local File來儲存Service資料

image

選擇剛剛的service.xml

image

打開APP.CONFIG,把這個地方的路徑拿掉,只留下檔名就好。

image

我們還會需要加上下面這一段在APP.CONFIG中。

<configuration>
<!--使用diagnostic-->
<system.diagnostics>
<trace>
<listeners>
<add type="Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener, Microsoft.WindowsAzure.Diagnostics, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
name="AzureDiagnostics">
<filter type="" />
</add>
</listeners>
</trace>
<sources>
<source name="Autoscaling General" switchName="SourceSwitch" switchType="System.Diagnostics.SourceSwitch" />
<source name="Autoscaling Updates" switchName="SourceSwitch" switchType="System.Diagnostics.SourceSwitch" />
</sources>
<switches>
<add name="SourceSwitch" value="Verbose, Information, Warning, Error, Critical" />
</switches>
</system.diagnostics>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.WindowsAzure.StorageClient"
publicKeyToken="31bf3856ad364e35"
/>
<!-- Auto-Scaling使用1.1版的StorageClient,將之轉為1.7版 -->
<bindingRedirect oldVersion="1.1.0.0"
newVersion="1.7.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>



打開service.xml,從剛剛的MSDN文章中擷取sample xml下來:



<?xml version="1.0" encoding="utf-8" ?>
<serviceModel xmlns="http://schemas.microsoft.com/practices/2011/entlib/autoscaling/serviceModel">
<subscriptions>
<subscription name="[subscriptionname]"
certificateThumbprint="[managementcertificatethumbprint]"
subscriptionId="[subscriptionid]"
certificateStoreLocation="CurrentUser"
certificateStoreName="My">
<services>
<service dnsPrefix="[hostedservicednsprefix]" slot="Staging">
<roles>
<role alias="AutoscalingApplicationRole"
roleName="[targetrolename]"
wadStorageAccountName="targetstorage"/>
</roles>
</service>
</services>
<storageAccounts>
<storageAccount alias="targetstorage"
connectionString="DefaultEndpointsProtocol=https;AccountName=[storageaccountname];AccountKey=[storageaccountkey]">
</storageAccount>
</storageAccounts>
</subscription>
</subscriptions>
</serviceModel>


其中:























































subscriptionname 要被scale的目標Cloud Service的subscription name
managementcertificatethumbprint 目標Cloud Service的certificate thumbprint
subscriptionid 目標Cloud Service的subscription id
hostedservicednsprefix 目標Cloud Service的DNS prefix,例如testabc.cloudapp.net的話,就是testabc
targetrolename 要被scale的Role Name,在Portal的Role上可以找到
targetstorage 要存放performance資料的Storage位置,我會把這個位置設為與目標Cloud Service存放performance資料的Storage account相同
storageaccountname Storage account name
storageaccountkey Storage account key
   



接著打開Rule.xml,一樣從MSDN取得sample xml



<?xml version="1.0" encoding="utf-8" ?>
<rules xmlns="http://schemas.microsoft.com/practices/2011/entlib/autoscaling/rules">
<constraintRules>
<rule name="default" enabled="true" rank="1" description="The default constraint rule">
<actions>
<range min="2" max="6" target="[AutoscalingApplicationRole]"/>
</actions>
</rule>
</constraintRules>
<reactiveRules>
<rule name="ScaleUpOnHighUtilization" rank="10" description="Scale up the web role" enabled="true" >
<when>
<any>
<greaterOrEqual operand="WebRoleA_CPU_Avg_5m" than="60"/>
</any>
</when>
<actions>
<scale target="[AutoscalingApplicationRole]" by="1"/>
</actions>
</rule>
<rule name="ScaleDownOnLowUtilization" rank="10" description="Scale up the web role" enabled="true" >
<when>
<all>
<less operand="WebRoleA_CPU_Avg_5m" than="60"/>
</all>
</when>
<actions>
<scale target="[AutoscalingApplicationRole]" by="-1"/>
</actions>
</rule>
</reactiveRules>
<operands>
<performanceCounter alias="WebRoleA_CPU_Avg_5m"
performanceCounterName="\Processor(_Total)\% Processor Time"
source ="[AutoscalingApplicationRole]"
timespan="00:05:00" aggregate="Average"/>
</operands>
</rules>



其中,[AutoscalingApplicationRole]就是目標Cloud Service的Role Name,要跟Service.xml中targetrolename的值一致。

2012年12月7日

[Azure]計算VHD被Charge的容量

最近常遇到客戶詢問為什麼VHD每天被Charge的容量不大對。

Azure VHD是儲存在Page Blob中,並且只有需要(至於怎麼樣叫做需要,目前沒有文件說明;我測試的結果,OS Disk幾乎是全部計入,Data Dis則是部分計入,但,目前沒有任何保證)的部分會被寫入。因此在計算用量時,並不是Portal上看到30G就是30G計費。我寫了一個小程式來計算每天charge的容量:(這個程式計算出的結果可能還是與報表上有誤差,因為我沒有將一些屬性所占用的容量計算進去,不過已經相當接近了)

            string accountName = string.Empty;
string keyValue = string.Empty;

Console.WriteLine("Please input Storage Name”);
accountName = Console.ReadLine();

Console.WriteLine("Please input Storage Account Key");
keyValue = Console.ReadLine();

var storage = new CloudStorageAccount(new Microsoft.WindowsAzure.Storage.Auth.StorageCredentials(accountName, keyValue), false);
var blobClient = storage.CreateCloudBlobClient();
var vhds = blobClient.GetContainerReference("vhds");
var blobs = vhds.ListBlobs();
float totalBytes = 0;
float totalGB = 0;
float summaryGB = 0;
foreach (var blob in blobs)
{
var pageBlob = vhds.GetPageBlobReference(blob.Uri.Segments[blob.Uri.Segments.Length - 1]);
pageBlob.FetchAttributes();
var pageRanges = pageBlob.GetPageRanges();
totalBytes += pageRanges.Sum(x => x.EndOffset - x.StartOffset);


                totalGB = totalBytes / (1024 * 1024 * 1024);
summaryGB += totalGB;
Console.WriteLine(string.Format("Total GB for VHD[{0}] is {1}, Daily usage is {2} GB",
blob.Uri.Segments[blob.Uri.Segments.Length - 1],
totalGB,
totalGB / 31));

}
Console.WriteLine("Total VHD Size in storage is {0} GB", summaryGB);
Console.WriteLine("Daily usage is {0} GB", summaryGB / 31);
Console.ReadLine();

About Me