本文主要介紹 3 個主要的 IIS 版本各自對 Web 請求的不同處理方式。
IIS 5.x 如何處理 ASP.NET 資源(如 .aspx、.asmx 等)請求。
IIS 5.x 運行在進程 inetinfo.exe 中,該進程寄宿著一個名為 World Wide Web Publishing Service(簡稱 W3SVC)的 Windows 服務。W3SVC 主要功能,包括 HTTP 請求的監聽、工作進程和配置管理(通過從元數據庫 metabase 中加載相關配置信息)等。
資源映射被存儲在 IIS 的 metabase 中。在安裝時,ASP.NET 修改 IIS 的 metabase,以確保 aspnet_isapi.dll 能夠處理所有的按照擴展名識別的資源。

圖 1 IIS 5.x 與 ASP.NET
當對一個資源的 HTTP 請求到達時,IIS 首先根據擴展名判斷確認資源類型。若為靜態資源(如圖像、文本文件、HTML頁面、沒有腳本的 ASP 頁面等),不使用外部模塊,由 IIS 直接處理,直接將內容以 HTTP 響應的形式返回;否則,動態資源(如 .aspx、.asp、.php 等),則通過擴展名從 IIS 腳本映射(Script Map)中找到相應的 ISAPI 動態鏈接庫。
ISAPI(Internet Server application PRogramming Interface)是一套本地 Win32 API,是 IIS 和其他動態 Web 應用或平臺之間的紐帶。ISAPI 定義在一個動態鏈接庫(DLL)文件中,ASP.NET ISAPI 對應的 DLL 文件為 aspnet_isapi.dll。ISAPI 支持 ISAPI 擴展(ISAPI Extension)和 ISAPI 篩選(ISAPI Filter),前者是真正處理 HTTP 請求的接口,后者可以在 HTTP 請求真正被處理前查看、修改、轉發或拒絕請求,如 IIS 可以利用 ISAPI 篩選進行請求驗證。
ISAPI 擴展不處理 .aspx 文件,而是起到調度程序的作用。它收集有關被調用的 URL 和底層資源的所有相關信息,然后將請求轉發給 ASP.NET 工作進程。
如果請求的是一個基于 ASP.NET 的資源類型,.asp 被 asp.dll 的 ISAPI 擴展進行處理,.aspx 被分配給 aspnet_isapi.dll 的 ISAPI 擴展,而 ASP.NET Extension 會創建 ASP.NET 工作進程(若該進程未啟動)。對于 IIS 5.x 來說,該工作進程為 aspnet_wp.exe。IIS 進程(aspnet_isapi.dll )與工作進程(aspnet_wp.exe)之間通過命名管道(Named Pipes)通信。
ASP.NET 工作進程表示 ASP.NET 運行庫環境,由一個名為 aspnet_wp.exe 的 Win32 非托管可執行文件組成,該文件上寄宿了 .NET 公共語言運行庫(CLR)。ASP.NET 工作進程激活 HTTP 管道,由它實際處理頁面請求。HTTP 管道是 .NET Framework 類的集合,負責編譯頁面程序集以及實例化有關的頁面類。
在工作進程(Worker Process)初始化過程中,.NET CLR 被加載,并構建一個托管環境。對于某個 Web 應用的初次請求,CLR 會為其創建一個應用程序域(Application Domain)。在應用程序域中,HTTP 運行時(HTTP Runtime)被加載,并創建相應的應用。寄宿于 IIS 5.x 的所有 Web 應用都運行在同一個工作進程(aspnet_wp.exe)的不同應用程序域中。
IIS 5.x 至少存在兩個不足:
為了解決第一個問題,IIS 6.0 將 ISAPI 動態鏈接庫直接加載到工作進程;
為了解決第二個問題,引入應用程序池(Application Pool)機制。可以為一個或多個 Web 應用創建應用程序池。由于每個應用程序池對應一個獨立的工作進程,從而為運行在不同應用程序池中的 Web 應用提供基于進程的隔離級別。IIS 6.0 工作進程名為 w3wp.exe。
除了以上兩點改進外,IIS 6.0 還有一些值得稱道的地方。其中最重要的一點就是創建了一個名為 HTTP.SYS 的 HTTP 監聽器。HTTP.SYS 以驅動程序形式運行在 Windows 內核模式(kernel Mode)下,它是 Windows 2003 的 TCP/IP 網絡子系統的一部分,從結構上看它屬于 TCP 之上的一個網絡驅動程序。
嚴格來說,HTTP.SYS 已經不屬于 IIS 的范疇,所以 HTTP.SYS 的配置信息也沒有保存在 IIS 的 Metabase 中,而是定義在注冊表中。HTTP.SYS 的好處如下:
圖 2 所示,描述IIS的結構和處理 HTTP 請求的流程。與 IIS 5.x 不同,W3SVC 從 inetinfo.exe 進程脫離出來(對 IIS 6.0 來說,inetinfo.exe 基本上可以看作單純的 IIS 管理進程),運行在另一個進程svchost.exe 中。W3SVC 的基本功能沒有變化,只是在功能的實現上做了相應改進。與IIS 5.x一樣,Metabase 依然存在于 inetinfo.exe 進程中。

圖 2 IIS 6.0 與 ASP.NET
當HTTP.SYS 監聽到用戶 HTTP 請求時,將其分發給 W3SVC,W3SVC 解析出請求的 URL,并根據從 Metabase 獲取的 URL與Web 應用之間的映射關系得到目標應用,并進一步得到目標應用運行的應用程序池或工作進程。若工作進程不存在(尚未創建或被回收),則為該請求創建新的工作進程。在工作進程初始化過程中,相應的 ISAPI 動態鏈接庫被加載。對于 ASP.NET應用來說,被加載的 ISAPI為aspnet_iaspi.dll。ASP.NET ISAPI 再負責進行 CLR 的加載、應用程序域的創建和Web應用的初始化等操作。

圖 3 IIS 6.0 中如何處理 Web 應用程序
IIS 7.0 在請求監聽和分發機制上又進行了改進。主要體現在引入了Windows進程激活服務(Windows Process Activation Service,WAS),將原來IIS 6.0 W3SVC的部分功能分流給了 WAS。對于IIS 6.0 W3SVC主要有三個功能:
IIS 7.0 將后兩個功能實現到 WAS中。WAS 的引入為了IIS 7.0 提供了對非 HTTP 協議的支持。WAS 通過監聽器適配器接口(Listener Adapter Interface)抽象出不同協議監聽器,如TCP監聽器、命名管道監聽器、MSMQ 監聽器。
圖 4 顯示 IIS 7.0 的整體構架及整個請求處理流程。無論是從 W3SVC接收到的 HTTP 請求,還是通過 WCF 監聽適配器接收到的請求,最終都會傳遞到 WAS。若相應的工作進程(或應用程序池)尚未創建,則創建;否則,將請求分發給對應的工作進程后續的處理。WAS在進行請求處理過程中,通過內置的配置管理模塊加載相關的配置信息,并對相關信息進行配置。與 IIS 5.x 和 IIS 6.0 基于 Metabase 的配置信息存儲不同,IIS 7.0 大都將配置信息以 xml 文件形式存儲,基本配置存放在 Applicationhost.config中。

圖 4 IIS 7.0 與 ASP.NET
IIS 5.x 和 IIS 6.0,IIS 與 ASP.NET 是兩個相互獨立的管道。在各自范圍內,具有自己的一套機制處理 HTTP 請求。兩個管道通過 ISAPI 連接。IIS 是第一道,對 HTTP 請求進行前期處理,如身份驗證,通過 ISAPI 將請求分發給 ASP.NET 管道。當 ASP.NET 完成對 HTTP 請求處理后,處理后的結果返回到 IIS,IIS 對其進行后期處理,如日志記錄、壓縮等,最終生成 HTTP 響應。
但是 IIS 5.x 和 IIS 6.0 的雙管道設計存在一些局限和不足。
為此,IIS 7.0 實現了兩者的集成。
新聞熱點
疑難解答