簡介
不管使用哪種底層平台,可靠性和性能都是對所有 Web 應用程序的主要要求,盡管從某種意義上講,這兩個要求是相互矛盾的。例如,要構建更可靠、更健壯的應用程序,可能需要將 Web 服務器與具體的應用程序分離,使應用程序在進程外工作。但是,如果在不同於 Web 服務器進程的內存環境中工作,應用程序將變慢。因此,需要采取合理的措施,以確保進程外代碼盡可能快地運行。
在構建 Microsoft? ASP.NET 運行時環境時,依據的設計原則即:充分考慮可靠性和性能。得到的 ASP.NET 進程模型包含了兩個系統元素 - 一個存在於 Web 服務器進程中的進程內連接器,一個外部的輔助進程。另外,ASP.NET 運行時結構的可伸縮能力很強,可以自動使用多處理器硬件中任意選定的處理器。這種模式被稱為“Web Garden”,它可以使多個輔助進程同時運行,而且各個進程均在獨立的處理器中。
高度概括起來,ASP.NET 運行時具有三大屬性:
應用程序和 ASP.NET 輔助進程之間完全分離。提供服務的輔助進程的壽命決不會影響應用程序的壽命。換句話說,當應用程序啟動並處於運行狀態時,輔助進程可以隨時終止。
盡管 ASP.NET 應用程序從不在 Web 服務器內采用進程內的方式運行,但大多數情況下,其總體性能仍接近於進程內應用程序的性能。
為 Web Garden 體系結構提供了內置的和可配置的支持。只要簡單檢查一下配置文件中的設置,輔助進程就可以克隆自己,以利用所有與進程密切相關的 CPU。因此,在大多數情況下,您在具備多處理器的計算機中獲得的可縮放性將呈線性增長的趨勢。(本文後面將詳細介紹此內容。)
本文將介紹 ASP.NET 運行時環境的組成元素,然後一步一步地講述從 URL 請求變為純 HTML 文本的“漫長而曲折”的過程。
除非另有說明,否則以下介紹中均指 ASP.NET 的默認進程模型,即 Microsoft? Internet Information Services (IIS) 5.x 中唯一的模型。
ASP.NET 結構的組件
執行 ASP.NET 應用程序需要宿主 Web 服務器的支持。在 Microsoft? Windows? 的 Server 平台中,Web 服務器由名為 inetinfo.exe 的 IIS 可執行文件表示。Windows 2000 及以上版本的操作系統本身均提供了 Web 服務器。但需要注意,在 Microsoft? Windows Server™ 2003 中,並未默認安裝 IIS 和 ASP.NET,必須通過單擊“控制面板”中的“添加或刪除程序”小程序將其添加到系統中。
IIS 是一個未托管的可執行程序,它提供了一個基於 ISAPI 擴展模塊和篩選器模塊的可擴展模型。通過編寫此類模塊,開發人員可以直接管理對特定資源類型的請求,並在各個預定義的步驟中接收當前請求。擴展和篩選器是一些 DLL,可以導出一些具有已知名稱和簽名的函數。這些插件組件是在 IIS 配置數據庫中注冊並配置的。
只有少數幾種被客戶端請求的資源類型由 IIS 直接處理。例如,對 HTML 頁面、文本文件、JPEG 和 GIF 圖像的傳入請求由 IIS 處理。對 Active Server Page (*.asp) 文件的請求通過調用名為 asp.dll 的 ASP 專用擴展模塊進行解析。同樣,對 ASP.NET 資源(例如,*.aspx、*.asmx、*.ashx)的請求將傳遞到 ASP.NET ISAPI 擴展。該系統組件是一個名為 aspnet_isapi.dll 的 Win32 DLL。ASP.NET 擴展可以處理多種資源類型,包括 Web 服務和 HTTP 處理程序調用。
ASP.NET ISAPI 擴展是一個 Win32 DLL,未集成托管代碼。它是接收和分派對各種 ASP.NET 資源的請求的控制中心。按照設計,該模塊存在於 IIS 進程中,在具有管理員權限的 SYSTEM 帳戶下運行。開發人員和系統管理員不能修改此帳戶。ASP.NET ISAPI 擴展負責調用 ASP.NET 輔助進程 (aspnet_wp.exe),而該進程又負責控制請求的執行。除了對請求進行安排以外,ASP.NET ISAPI 還監視輔助進程的運行情況,並在性能降低到一定程度時將進程取消。
輔助進程是一小段 Win32 shell 代碼,集成了公共語言運行庫 (CLR) 並運行托管代碼。它負責處理對 ASPX、ASMX 和 ASHX 資源的請求。一般來說,此進程在一台給定的計算機中只有一個實例。所有當前激活的 ASP.NET 應用程序均在其中運行,每個應用程序都位於一個獨立的 AppDomain 中。但是,如前所述,輔助進程支持 Web Garden 模式,即進程的相同副本都運行在與進程密切相關的 CPU 中。(更多內容,請參閱本文後面的“Web Garden 模型”部分。)
ISAPI 和輔助進程之間的通訊是使用一組命名管道進行的。命名管道是一種 Win32 機制,用於跨進程邊界傳輸數據。顧名思義,命名管道的工作方式與管道相似:在一端輸入數據,在另一端輸出相同的數據。建立的管道既可以連接本地進程,也可以連接遠程計算機上運行的進程。對於本地進程間通訊,管道是 Windows 中的最有效、最靈活的工具。
為確保獲得最優性能,aspnet_isapi 使用異步命名管道來將請求轉發給輔助進程並獲得響應。另一方面,輔助進程在需要查詢有關 IIS 環境的信息(即服務器變量)時又使用同步管道。aspnet_isapi 模塊創建固定數量的命名管道,並使用重疊的操作以通過小的線程池處理同一時間進行的連接。當通過管道進行的數據交換操作結束後,完成例程將斷開客戶端,並重新使用管道實例為新的客戶端服務。線程池和重疊操作均可以保證使 ASP.NET ISAPI 的性能達到令人滿意的水平。但是,aspnet_isapi 擴展決不會處理 HTTP 請求。