MVC之前的那點事兒系列,是筆者在2012年初閱讀MVC3源碼的時候整理的,主要講述的是從HTTP請求道進入MVCHandler之前的內容,包括了原創,翻譯,轉載,整理等各類型文章,當然也參考了博客園多位大牛的文章,對此表示感謝,這次有時間貼出來,希望對大家有用。
主要內容
本文講解的是:服務器接受Http Request請求之后,是如何進入.Net CLR,從而進一步操作的。
我們大家都知道,IIS必須先接受請求,然后才能有機會進入CLR,但對請求(request)是怎么從Web服務器傳送到ASP.NET運行時的卻不甚了解。IIS由於版本的不同,在進入CLR時候方式可能有所不同,本章節將就IIS5/6/7的三本版本的進入方式給予解釋,通過對這些底層機制的了解,可以讓我們對 ASP.net 有更深的理解。。
IIS 5 的 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 的變量。
IIS 6 的 ASP.net 請求處理過程
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。
IIS 7 的 ASP.net 請求處理過程
步驟 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,其它不需要):
http://referencesource.microsoft.com/
參考資料:
http://dotnetslackers.com/articles/iis/ASPNETInternalsIISAndTheProcessModel.aspx
http://dotnetslackers.com/articles/iis/ASPNETInternalsIISAndTheProcessModel2.aspx
http://www.cnblogs.com/riccc/archive/2007/07/08/asp-net-internals-iis-and-the-process-model.html
http://learn.iis.net/page.aspx/243/aspnet-integration-with-iis/
http://learn.iis.net/page.aspx/101/introduction-to-iis-architecture/
http://www.west-wind.com/presentations/howaspnetworks/howaspnetworks.asp
http://www.cnblogs.com/zhaoyang/archive/2011/11/16/2251200.html
http://www.dotnetfunda.com/articles/article821-beginners-guide-how-iis-process-aspnet-request.aspx
同步與推薦
本文已同步至目錄索引:MVC之前的那點事兒系列
MVC之前的那點事兒系列文章,包括了原創,翻譯,轉載等各類型的文章,如果對你有用,請推薦支持一把,給大叔寫作的動力。