Windows Azure提供了一個叫做Role的概念,每個Role可以被認為是一段程式,與普通的應用程式不同的是這段程式可以同時在一台或者多台機器上運行。每個Role可以有多個執行個體(Instance),每個執行個體就對應一台虛擬機器。對同一個Role而言,它所有的執行個體執行的程式都是相同的。現在有兩種類型的Role:Worker Role(工作者角色)和Web Role(Web 角色)。1所示:
圖1 Web Role和Worker Role
Web Role:是一個 Web 應用程式,一個Web角色就是運行在IIS上的一個Web應用程式,它可以通過HTTP或HTTPS與外界通訊,一般來說,Web角色響應請求,執行一個動作,然後等待下一個請求的到來。它作為用戶端展現層的應用程式,所有與用戶端互動的功能都是由這個角色來處理,因此它可以支援 ASP.NET Web Form、ASP.NET MVC 以及基於FastCGI 核心執行的應用程式,像是 PHP、JSP 或其他 CGI 應用程式。但 Web Role 只支援 HTTP 與 HTTPS 通道,因此若要使用 Web Role 開發服務的話,只有 ASP.NET Web Service(ASMX Service)或是使用 HTTP 通道的 WCF Service 可以使用。由圖1可以建立的Web Role應用類型也說明了這一點。
Worker Role:是一種後台執行(Running On Background)的應用程式,運行.Net架構代碼的後台進程應用程式。Worker Role與 Web Role 不同的是,它通常不與使用者直接互動,而是在後台訪問任何網路資源、資料來源並進行操作。它不開放外部存取介面,但是在接到命令後會毫無怨言地依次執行(Queue service裡的訊息佇列能引導它的工作),這有點類似架設在 Windows Azure 上的 Windows Service,而且它又可以支援 HTTP/HTTPS 或 TCP 的通訊模式,特別適用於不限 HTTP 通訊的服務應用程式,像是一般的 WCF 服務。
通常開發 Windows Azure 應用程式時,只需要Web Role 就已足夠,出於應用程式本身的架構和擴充性考慮,採用一些架構和設計可以把應用程式程式的功能分層,並把應用程式的一些邏輯處理分配給 Worker Role 是必要的,因為 Worker Role 會在幕後處理工作,Web Role 只需要應付前端的使用者介面互動即可,將工作交給適當的成員來執行,可以有效提升應用程式的執行效能,也可以降低開發時的藕合性。
本文使用了微軟Windows Azure Code Samples 裡的FullTrust 樣本來給大家做個簡單示範。它讓你感受到雲端運算開發的樂趣。由於是使用的已有案例,感興趣的讀者可以從http://code.msdn.microsoft.com/windowsazuresamples
下載完整的執行個體代碼。這個樣本示範了兩個功能:通過P/Invoke,從管理代碼中調用活動代碼;子進程迴圈往複的運行命令列指令碼。這裡我們先給出啟動並執行結果,然後對開發過程和核心代碼做一個分析。運行項目,自動開啟一個Web頁面,2所示:
圖2 Web Role的 Default頁面
在Web Role的Default頁面,點擊重新整理按鈕,可以重新整理進程系統時間資訊。而ExcuteProcess.aspx頁面是一個ASP.Net的頁面,作為一個子進程,當子進程結束後,輸出資訊,3所示:
圖3 Web Role的執行結果
看到web role的運行結果後,我們把注意力重點轉向Development Fabric,在這裡我們將看到Worker Role的運行結果。要查看Development Fabric的結果,工作列通知區域看到Development Fabric,Development Fabric是一個模擬環境,在本機類比運行角色執行個體。在左側的工具按鈕中選擇4所示的按鈕。
圖4 選擇Development Fabric
選擇顯示Development Fabric,開啟介面5所示:
圖5 Fabric 的web Role
在圖5中,我們可以看到web role的entrypoint是OnStart方法,同時也調用了Run方法。Worker Role的運行結果6所示:
圖6 Fabric 的 Worker Role
在Worker Role中,可以看到進程被調用,執行了HelloWord.cmd,同時顯示重新整理的系統時間。
接下來我們介紹開發過程和核心代碼。
步驟一:建立項目
開啟VS 2010 建立雲端運算項目FullTrust,在彈出1所示的介面中,分別選擇Web Role和Worker Role,並進行重新命名為FullTrust_WebRole和FullTrust_WorkerRole。在重新命名的時候,有個小技巧,把角色類型選到雲端服務解決方案中後,直接右擊就可以重新命名,當然也可以在項目中進行重新命名,所不同的時候,項目名稱改了,但是在本地磁碟隱藏檔的檔案夾名稱並沒有改變。
建立完工程後,在FullTrust_WebRole項目中添加Default和ExecuteProcess頁面,HelloWorld.cmd指令碼;在複製HelloWorld.cmd指令檔到FullTrust_WorkerRole。
這樣我們建立項目的工作告一段落。
步驟二:編寫Web Role功能
在FullTrust_WebRole中,default頁面點擊按鈕顯示重新整理時間,核心代碼如下:
按鈕事件代碼:
protected void Button1_Click(object sender, EventArgs e)
{
UpdateProcessInfo();
}
更新進程資訊方法:
protected void UpdateProcessInfo()
{
……
if (GetProcessTimes(Process.GetCurrentProcess().Handle,
out createdTime,
out exitedTime,
out kernelTime,
out userTime))
……
}
GetProcessTimes方法是一個系統函數,用於取得進程時間。
在ExecuteProcess.aspx中,有關鍵的一句:
<pre><% Run("~/HelloWorld.cmd",""); %></pre>
這句調用了ExecuteProcess.cs的Run函數,代碼如下:
protected int Run(
string cmdPath,
string arguments)
{
var process = new Process();
var startInfo = process.StartInfo;
……
process.ErrorDataReceived +=
(sender, evt) =>
{
Response.Write("");
WriteLine(evt.Data);
Response.Write("");
};
process.OutputDataReceived +=
(sender, evt) =>
{
WriteLine(evt.Data);
};
WriteLine("Executing: " + Path.GetFileName(startInfo.FileName));
WriteLine("============= Output =======================");
process.Start();
process.BeginErrorReadLine();
process.BeginOutputReadLine();
process.WaitForExit();
WriteLine("============================================");
var elapasedTime = process.ExitTime - process.StartTime;
WriteLine("Exit Code: {0}", process.ExitCode);
WriteLine("Elapsed Time: {0}", elapasedTime);
return process.ExitCode;
}
這個函數調用子進程並輸出命名行指令碼結果。HelloWorld.cmd的腳步內容如下:
@echo off
echo Hello World!
exit /B 0
步驟三:編寫Worker Role功能
在Worker Role裡,同樣可以調用HelloWorld.cmd,把ExecuteProcess.cs的Run函數複製過去,其實在這裡,我們可以把一些公用的代碼剝離出來,放在一個公用的類庫裡,方便調用。每一個Worker Role都是繼承RoleEntryPoint的,在workerrole.cs裡的run方法裡要調用Run函數以便運行HelloWorld.cmd。
同時我們還需要把進程的日誌記錄進去,以便查看調用情況,其代碼如下:
protected void LogProcessTimes(Process process)
{
System.Runtime.InteropServices.ComTypes.FILETIME createdTime;
System.Runtime.InteropServices.ComTypes.FILETIME exitedTime;
System.Runtime.InteropServices.ComTypes.FILETIME kernelTime;
System.Runtime.InteropServices.ComTypes.FILETIME userTime;
if (GetProcessTimes(process.Handle,
out createdTime,
out exitedTime,
out kernelTime,
out userTime))
{
WriteLine(" Real Time: {0}", FiletimeToDateTime(exitedTime) - FiletimeToDateTime(createdTime));
WriteLine(" User Time: {0}", FiletimeToTimeSpan(userTime));
WriteLine("System Time: {0}", FiletimeToTimeSpan(kernelTime));
}
}
在run函數中,進程結束後調用此函數,把調用的時間資訊記錄到日誌裡去,因此我們在圖6中可以看到記錄的日誌資訊。
步驟四:編譯調試
所有代碼編寫完成後,編譯項目,使用Development Fabric類比真實環境進行調試和運行。由於我們沒有設定服務資訊,因此沒有ServiceConfiguration.cscfg和ServiceDefinition.csdef檔案進行設定,這需要根據具體項目來確定。
要調試和運行,首先要設定有雲表徵圖的 FullTrust項目為啟動項目。設定Deault.aspx為起始頁就可以了。如果編譯一次通過,使用CTRL+F5或者調試|不調試開始運行,就可以對項目自動進行打包,類比運行了,其介面2~6所示。
在真實情境中,調試運行後,就需要部署項目,關於具體部署的過程和步驟,這裡不再詳細介紹,感興趣的讀者可以參考微軟中國雲端運算部落格。
在本例中,我們只是簡單的介紹了如何開發兩種角色的應用,還有更多比這更複雜的應用來使用這兩種角色。在開發過程中,我們要區分Web Role和Worker Role的功能。有些應用程式類型有時候也會讓開發人員不得不選擇使用 Worker Role 來進行處理,最典型的例子就是排隊類應用程式(例如線上訂票系統),Web Role 無法使用排隊方式來執行,而且這類型的應用程式都會需要用到 Queue 來處理要求,而 Web Role 亦無法開發可定時(scheduled,例如每分鐘或每五分鐘)由 Queue 中提取資料處理的應用程式,因此 Worker Role 就是這類型應用程式的最佳類型。
Visual Studio Tools for Windows Azure 的雲端應用程式項目可以允許一次部署多個 Windows Azure 的應用程式類型(最多五個不同的角色),但是請注意,每一應用程式類型都會被掛載在獨立的 Virtual Machine 中,而運算資源的計費(後面會介紹到)是以 Virtual Machine 為單位計價的,因此如果不是一定要部署上去的應用程式,請不要封裝在雲端應用程式中。同時若只是要測試,建議先在本機(資源可以連到 Windows Azure)測試完畢,再部署到雲端。
總結
本文介紹了Windows Azure中的兩種角色:Web Role和Worker Role,幾乎所有的應用開發都包含在這兩種角色中,Web Role應用類似我們熟悉的Asp.Net應用程式,Worker Role類似於Windows /Web Service。通過一個FullTrust案例的介紹,相信大家對這兩種角色的功能和開發過程已經瞭然於胸了。
IT168:http://tech.it168.com/a2010/0612/1066/000001066069_all.shtml