MVC之前的那點事兒系列,是筆者在2012年初閱讀MVC3源碼的時候整理的,主要講述的是從HTTP請求道進入MVCHandler之前的内容,包括了原創,翻譯,轉載,整理等各類型文章,當然也參考了部落格園多位大牛的文章,對此表示感謝,這次有時間貼出來,希望對大家有用。
本文講解的是:伺服器接受Http Request請求之後,是如何進入.Net CLR,進而進一步操作的。
我們大家都知道,IIS必須先接受請求,然後才能有機會進入CLR,但對請求(request)是怎麼從Web伺服器傳送到ASP.NET運作時的卻不甚了解。IIS由于版本的不同,在進入CLR時候方式可能有所不同,本章節将就IIS5/6/7的三本版本的進入方式給予解釋,通過對這些底層機制的了解,可以讓我們對
ASP.net 有更深的了解。。

IIS5核心特征是:IIS是允許在一個叫InetInfo.exe的程序上的,是以無論是aspx頁面還是html頁面都是通過這個程序處理的,其中,由于aspx頁面擴充名映射到了aspnet
ISAPI.DLL上,是以如果頁面是aspx的話,aspnet ISAPI.DLL則建立aspnet_wp這個Worker
Process,并在初始化的時候加載CLR,是以這是一個托管的環境。
需要注意的幾點是:
同一台伺服器隻能運作一個 aspnet_wp 程序,也就是說所有的ASP.NET Web Application都在同一個Worker
Process 中,但是不意味着他們共享同一個context和資料庫,
ASP.NET裡有個AppDomain的概念,每個站點或虛拟目錄都對應一個單獨的AppDomain,每個AppDomain是隔離的,有自己獨立的context上下文,是以安全沒問題,是以我們的結論是:ASP.NET程式是繼續AppDomain的,而不是基于Process的。
ASP.NET ISAPI 不但負責建立 aspnet_wp Worker Process,而且負責監控該程序,如果檢測到
aspnet_wp 的 Performance 降低到某個設定的下限,ASP.NET ISAPI
将結束掉該程序,在Request來了以後,ASP.NET ISAPI 将重新建立新的 aspnet_wp Worker Process。
由于 IIS 和 Application
運作在他們各自的程序中,他們之間的通信必須采用特定的通信機制。由于之間的通信是同機器不同程序的通信(local interprocess
communications),處于Performance的考慮,他們之間采用基于Named pipe的通信機制。ASP.NET ISAPI和Worker
Process之間的通信通過他們之間的一組Pipe實作。同樣處于Performance的原因,ASP.NET ISAPI 通過異步的方式将Request
傳到Worker Process 并獲得 Response,但Worker Process 則是通過同步的方式向 ASP.NET ISAPI 獲得一些基于
Server 的變量。
IIS6和IIS5有3個非常不同的地方:接受請求(Http.sys),應用程式池(Application Pool),w3wp.exe Worker
Process。
在IIS5裡,InetInfo.exe附件監聽并處理請求(Request),但在IIS6裡,伺服器是通過一個新元件Http.sys來接受請求(Request)。
Http.sys接收到http請求的時候,它會根據IIS中的 Metabase 檢視該基于該 Request 的 Application
屬于哪個Application Pool, 如果該Application Pool不存在,則建立之。否則直接将 request 發到對應Application
Pool 的 Queue中。
每個 Application Pool 對應着一個Worker Process:w3wp.exe。在IIS Metabase 中維護着
Application Pool 和worker process的Mapping。WAS(Web Administrative
service)根據這樣一個mapping,将存在于某個Application Pool Queue的request 傳遞到對應的worker
process(如果沒有,就建立這樣一個程序)。在 worker process 初始化的時候,加載ASP.NET ISAPI,ASP.NET ISAPI
進而加載CLR。
注意:IIS5和IIS6還有一個差別是,在IIS5裡ASP.NET ISAPI建立aspnet_wp Worker
Process,進而加載CLR,但在IIS6裡是w3wp通過Application Pool的map關系運作以後,才加載ASP.NET
ISAPI,然後加載CLR。
步驟 1 到 6 ,是處理應用啟動,啟動好後,以後就不需要再走這個步驟了,上圖的8個步驟分别如下:
HTTP.sys監聽攔截用戶端請求開始處理。
HTTP.sys通過配置資訊聯系WAS擷取相關資訊。
WAS 向配置存儲中心請求配置資訊。applicationHost.config。
WWW 服務接受到配置資訊,配置資訊指類似應用程式池配置資訊,站點配置資訊等等。
WWW 服務使用配置資訊去配置 HTTP.sys 處理政策。
WAS為這個請求對應的應用程式池(Application Pool)開啟W3WP Worker Process。
W3WP Worker Process處理以後,将Response傳回給HTTP.sys。
用戶端接受到Response内容。
W3WP.exe 程序中又是如果處理得呢?? 取決于IIS 7 的應用程式池托管管道模式是什麼,IIS7目前有2個模式:
經典模式和內建模式。兩種模式下的處理方式是不一樣,看如下差別:
IIS7經典模式:
IIS7的經典模式和IIS6的處理方式是一樣的,使用者發送HTTP Request請求以後, IIS會先行處理,IIS會根據HTTP
Request的類型進行篩選,如果是HTML 靜态網頁就由 IIS 自行處理,如果不是,就根據具體要求的内容類型,分派給各自的 IIS ISAPI
extension;如果要求的内容類型是 ASP.NET,就分派給負責處理 ASP.NET 的 IIS ISAPI extension,也就是
aspnet_isapi.dll,然後再進入CLR。
IIS7內建模式:
IIS7內建模式是一個偉大的改進,已經預加載了CLR(不在依靠之前IIS版本的aspnet_ISPAI.DLL),也就是說所有的HTTP
Request請求都要經過ASP.NET來處理(包括html, php等),也因為 ASP.NET 的諸多功能已經成為 IIS 7 的一部份,是以 ASP
程式、PHP 程式或靜态 HTML 網頁等類型的要求,也能使用像是Forms認證(Forms Authentication)或輸出緩存(Output
Cache)等 ASP.NET 2.0 的功能(但須修改 IIS 7 的設定值),也因為 IIS 7 允許自行以 ASP.NET API 開發并加入子產品,是以
ASP.NET 網頁開發人員将更容易擴充 IIS 7 和網站應用程式的功能,甚至能自行以 .NET 編寫管理 IIS 7 的程式(例如以程控 IIS 7
以建置網站或虛拟目錄)。
總結:
不同的IIS版本進入CLR的方式是不一樣的,其中IIS版本之間最大的改變時:
IIS5 到 IIS6 的改進,主要是 HTTP.sys 的改進。
IIS6 到 IIS7 的改進,主要是 ISAPI 的改進。
提示:從下一章節開始,我們将進入微軟.NET4和MVC3源碼進行深入分析,是以該繼續後面的章節之前,請先下載下傳這些源代碼,位址如下(隻需要下載下傳.NET4和MVC3,其它不需要):
本文已同步至目錄索引:
MVC之前的那點事兒系列文章,包括了原創,翻譯,轉載等各類型的文章,如果對你有用,請推薦支援一把,給大叔寫作的動力。