之前在網上看過很多對這方面的講解,但個人覺得看下來過於 "深奧",不容易理解,所以想用更簡單的方式進行闡述,便於理解。
本次我們重點分析用戶請求到頁面呈現過程中Web服務器的處理過程。我們從ASP.NET站點的一個頁面請求開始說起,先看下面對於某個請求的簡單執行模型
(注意這是對asp.net站點Index.aspx頁面的第一次請求,所以需要進行動態編譯):
我們通過ASP.NET的執行模型簡單的描述了一次web請求過程,注意在不同的IIS版本中,處理模型和通信方式是不一樣的,在IIS7.0以上asp.net已經作為一個模塊集成在了IIS中。
我們繼續對上面的流程進行相關闡述:
- 首先我們通過瀏覽器發送頁面請求至IIS服務器,由於是第一次請求index.aspx,IIS會將請求轉交給ASP.NET后進入編譯期(加載aspnet_isapi.dll)
- 由於ASP.NET是通過CLR運行,而CLR只認識MSIL(微軟中間語言),所以ASP.NET會判斷代碼是否已被編譯,若未被編譯則會走二次編譯流程,否則跳過編譯進入執行期,
- 在執行期進行一系列的模塊處理,然后返回請求
接着我們來看看什么是二次編譯?
二次編譯:
將源代碼文件通過編譯器編譯成中間語言代碼和元數據,執行時再編譯為本地機器語言代碼的過程。
感覺不好理解?那就直接看圖吧!
如上,我們把這兩次編譯的過程叫做二次編譯。
二次編譯在站點頁面首次被請求時執行,ASP.NET判斷已經編譯過的不會再走編譯流程。
看完二次編譯然后我們再對asp.net站點Index.aspx進行首次請求:
用戶請求—>IIS服務器—>ASP.NET—>二次編譯—>MSIL(代碼編譯器)—>本機語言(JIT)—>執行期
- 創建應用程序域
- 初始化核心對象
- 啟動應用程序
- 根據配置對請求進行處理,一系列HTTPModule和HTTPHandler
最后請求通過一層層HttpModule和HttpHandler后進入頁面的初始化,加載,呈現,用戶操作,卸載。
這就解釋了為什么我們的站點頁面第一次被請求的時候總是慢一點的原因,原因就是第一次請求時走了編譯的過程,加載了一系列初始化的東西。
如果我有多個應用程序池多個站點都部署在一台IIS服務器,我發一個請求IIS如何知道我請求的是哪個呢?這里就會提到到一個HTTP.SYS組件。
其實在IIS將請求交給ASP.NET之前,會最先觸發HTTP.SYS的響應,由HTTP.SYS負責把請求傳入相應的應用程序池。然后繼續走上面的ASP.NET流程
每當創建一個應用程序池,該池的ID就會生成並在HTTP.SYS文件中注冊。
總結:
如上圖:在執行期會進行一系列的操作,然后通過HttpModule模塊到達HttpHandler處理程序,最后開始進入頁面的生命周期相關的東西。
看完如果對你有幫助還可關注公眾號CodeL獲取更多內容。