1. 程式人生 > >Http請求處理整個過程

Http請求處理整個過程

admin 轉發 速度 客戶端 OS 有效 施工 功能實現 。net

一,服務器接受http請求的實際處理過程

技術分享圖片

二,當客戶端將請求通過網絡傳送到服務器時,HTTP.SYS會在內核模式下實時監聽當前的http請求。Http.sys功能如下描述:

技術分享圖片

http.sys 是一個位於Win2003和WinXP SP2中的操作系統核心組件

能夠讓任何應用程序通過它提供的接口,以http協議進行信息通訊。
  溫馨提示:如果用戶不慎刪除了該驅動文件,不用擔心,該驅動會在下次系統啟動時重建。是一個刪不掉的系統核心組件!實用程序結束該驅動,該驅動也會馬上重新創建(只有粉碎文件才不能馬上重建,但粉碎後,下次啟動會重建)。
  微軟在Windows 2003 Server裏引進了新的HTTP API和kernel mode driver Http.sys,目的是使基於Http服務的程序更有效率。這個改變的直接收益者就是IIS 6.0 和 asp.net.
  其實在Windows XP安裝SP2後,Http.sys已經出現在系統裏了,但事實上,操作系統並沒有真的使用這個內核級驅動,而XP上自帶的IIS 5.1也沒有使用HTTP API。
  新的HTTP API裏最核心的變化都封裝在Http.sys這個kernel mode driver裏了。在此之前,基於HTTP協議的程序都是在User mode下運行的,而且必須自己處理諸如軟件中斷、context switch、線程調度等等問題,並且往往無法自由接觸系統資源。過去,HTTP服務器,如IIS, Apache等都是利用Winsock API來創建一個User mode下的network listener。Network listener通常獨自(i.e.: per application or per thread basis)占用一個IP端口。通俗點說,就是在同一時間只有一個應用程序可以監聽一個端口,這在有些時候是一個不太令人舒服的限制。
  新的Http.sys帶來的好處大致有如下一些:
  1. 緩存 - 靜態的內容現在被緩存於內核模式下,這使服務響應速度更快

  2. 記錄 (Log)-IIS的log功能更快且標準化了
  3. 帶寬控制 - greater scalability control and throttling
  4. 可靠性 - 所有的服務請求會在Http.sys裏暫存入隊列,而不是由服務程序本身來處理,這樣,即使服務程序重啟,尚未被處理的請求也不會丟失了
  5. IP端口重用 - 現在,只要是通過Http.sys管理的端口(基本包括了那些著名的端口,比如80),都可以同時允許多個程序同時監聽了。

Http.sys是IIS 6.0使用的新型偵聽器。在IIS 6.0出現之前,inetinfo.exe完成偵聽HTTP請求的功能,同時還要將請求轉發給對應的處理程序。從IIS 6.0開始,偵聽器與inetinfo.exe分離開來,inetinfo.exe在用戶模式下運行,Http.sys則完成偵聽HTTP請求的功能,在 內核模式下運行。

1. 內核模式和用戶模式

在Windows Server 2003中,一個進程既可以運行於內核模式,也可以運行於用戶模式。如果一個進程運行於內核模式,那麽這個進程就可以訪問所有硬件和系統數據;如果一個進 程運行於用戶模式,那麽這個進程不能直接訪問硬件,而且訪問系統數據時也會受到限制。在Intel處理器架構中,內核模式運行於ring 0之內,而用戶模式運行於ring 3。通過在內核模式運行Http.sys,偵聽器可以直接訪問TCP/IP協議棧,但是又能夠位於WWW服務之外,這樣就不會受到應用程序中代碼缺陷的影 響,也不會因為應用程序崩潰而出現問題。

通過在內核模式運行,Http.sys獲得了比較高的優先級,與先前版本的IIS相比,對HTTP請求響應速度比較快。Http.sys不僅因為具 有較高的優先級而提高了IIS的性能,而且,還可以在等待應用程序響應(即使應用程序已經停止響應)的同時,將請求進行排隊。在IIS 6.0中,每個應用程序池都擁有一個內核模式隊列,Http.sys可以將請求轉發給合適的隊列。所以,在IIS 6.0中,當我們對性能進行調優時,可以將負載比較重的應用程序分隔到不同的應用程序池,從而使負載比較輕的應用程序不必與負載較重的應用程序共享同一個 隊列。對每個應用程序池而言,隊列規模是可配置的。

Http.sys可以將請求進行緩存,並盡可能地在內核模式中完成對請求的服務。如果某個請求的響應已經得到了緩存,那麽IIS就無須重新處理這個 請求,Http.sys只需要將這個響應從緩存中取出,這樣就繞開了所有的IIS功能,從而也就避免了重新處理。這些已緩存的請求都保存在內存中,並且不 允許換出,因此,盡可能地增大系統內存是提高IIS性能的一種簡單有效的方法。

盡可能地增大系統內存還能夠減少inetinfo.exe的磁盤交換次數。inetinfo.exe運行於用戶模式,可以在必要時交換到磁盤空間。如果系統內存過少,那麽IIS的性能會急劇下降。

2. 其他Http.sys功能

針對HTTP請求和響應,Http.sys還能夠處理TCP/IP連接,包括創建連接和斷開連接。因為Http.sys直接運行於TCP/IP協議棧之上,因此還需要處理連接和超時,以及連接數限制和帶寬不足。此外,Http.sys還需要處理日誌。

Http.sys通過執行兩項重要功能來提高IIS 6.0的性能。首先,Http.sys在內核模式下對請求進行緩存,因此,為了給某個請求提供服務,如果該請求所需內容最近已經為先前某個請求提供服務 (無論是提供靜態內容還是提供動態內容),那麽可以在內核模式下直接為該請求提供其所需內容,而不需要再切換到用戶模式下在inetinfo.exe進程 中運行。

Http.sys還可以將請求進行排隊,由合適的工作進程完成對請求的服務。每個應用程序池都擁有自己的隊列,隊列的規模是可以配置的,這樣,我們 可以對某個具體應用程序池的性能進行調優。針對可能會發生失效的應用程序,使用隊列還有另一個優點,就是針對失效應用程序的請求仍然會保存在隊列中,直到 隊列中保存的請求總數達到該隊列的上限。當應用程序能夠重新進行響應時,這些請求仍然能夠得到處理;此外,通過自動重啟發生失效的應用程序池,還能夠降低 響應時間,從用戶看來,應用程序的響應僅僅是稍微延遲了一點。

三,Http.sys是如何知道當前這個請求是給哪個應用程序池?????

    當實施工程師創建應用程序池的時候,會將對應的應用程序池ID註冊到註冊表裏面,這個註冊表是Http.sys裏面的。那麽Http.sys會根據當前請求送到對應的應用程序池裏面。

四,IIS如何處理

Web 服務器 VS Web 應用程序

在了解 IIS 如何處理 ASP.NET 請求之前,我們必須要清楚 Web 服務和 Web 應用程序之間的界限。Web 服務器與 Web 應用程序之間的關系,就像 操作系統 與 普通桌面應用程序之間的關系一樣 —— 一個提供了運行環境,一個提供實際的業務功能實現。簡短一點說,一個是宿主 Host ,一個是應用程序 Application。操作系統能夠為各種各樣的應用程序提供運行環境,而 Web 服務器是構建於操作系統之上的、具有針對性的應用程序宿主(針對 Web 應用程序),就像 Windows 服務一樣。沒錯,如果你對 Windows 服務的了解多過 Web 服務器,那麽使用類比法通過 Windows 服務來了解 Web 服務器是個不錯的選擇(事實上用 Web服務 替代 Web服務器來表述可能會更合理一點,但這樣就很容易將 Web服務 與 .NET Web Service 技術搞混)。

IIS(Internet Information Services)

在中文操作系統中,IIS 被稱為 互聯網信息服務 —— 這是 Microsoft 公司提供的運行於 Windows 操作系統之上的 Web 服務器,它的功能絕不只是能處理 ASP.NET 請求。但本文要嘗試講明的是 IIS 如何處理 ASP.NET 請求,所以,我們可以假設“IIS就是為 ASP.NET 而生的”。

IIS 如何處理 ASP.NET 請求

作為 Web 服務器,IIS 的主要工作是接收請求並通過Web管理服務(Web Admin Services,WAS)將請求分發給不同的應用程序池。

應用程序池接收到請求後,根據當前運行狀況將請求投放給某個工作進程(w3wp.exe),工作進程會依據請求 url 的相關特性(比如後綴 aspx)選擇和加載特定的 ISAPI(Internet Server Application Programming Interface,網絡服務應用編程接口)。

ASP.NET 對應的 ISAPI 為 aspnet_isapi.dll, 它將構造一個 HttpRuntime 作為應用程序入口,從這裏開始,請求將會來回經過HttpApplication 中的一序列 HttpModule 和 HttpHandler,然後做出響應。

aspnet_isapi.dll

.NET 程序員應該都知道,想要 ASP.NET 正常運行,必須安裝 .NET Framework。但有時候明明已經安裝了 .NET Framework,部署在 IIS 上的網站卻怎麽也不能正常訪問,然後在網上折騰搗鼓,終於在運行 aspnet_regiis 並設置應用程序池的 .NET Framework 版本之後就可以正常訪問了。 沒錯,運行 aspnet_regiis 的目的是為了 將相應版本的 .NET Framework 註冊到 IIS ,如果你是先安裝 IIS ,後裝 .NET Framework, 就無需那麽復雜 —— .NET Framework 會自動註冊。

.NET Framework 註冊到 IIS 時,就會給 IIS 添加相應的 ISAPI —— aspnet_isapi.dll。

IIS 如何知道哪個請求該分發給哪個應用程序池

IIS 內核模塊(Kernel Mode)包含一個 HTTP.SYS 文件。

向 IIS 添加一個應用程序池的同時會生成一個對應的標識ID,並被記錄到 HTTP.SYS(事實上記錄的是 url 與 應用程序池之間的對應關系)。

任何來自客戶端的 HTTP 請求都將首先觸發 HTTP.SYS 。事實上 HTTP.SYS 本身不會執行任何代碼,它僅僅是監聽客戶端的 HTTP 請求。HTTP 請求包含了 Web 站點的主機(或 IP)、端口和資源路徑信息,即 url —— 根據映射,IIS 自然就知道如何分發請求給應用程序池了。

Http請求處理整個過程