[ASP.NET]談談IIS與ASP.NET管道


作為一個Asp.Net平台開發者,非常有必要了解IIS和Asp.Net是如何結合,執行我們的托管代碼,以及Asp.Net管道事件的.

 

本節目錄

 

IIS 5.x

InetInfo.exe與W3SVC服務

IIS 5.x運行在進程InetInfo.exe中,在該進程中一個最重要的服務就是名為World Wide Web Publishing Service(簡稱W3SVC)的Windows Service。

W3SVC的主要功能包括HTTP請求的監聽、工作進程的管理以及配置管理(通過從Metabase中加載相關配置信息)等。

 

請求資源(根據擴展名區分靜態和動態資源)

靜態文件,直接返回文件內容。

動態資源,通過擴展名從IIS的腳本影射(Script Map)找到相應的ISAPI Dll。

 

ISAPI

ISAPI是Internet服務器API(Internet Server Application Programming Interface)的縮寫.是IIS和其他應用的紐帶.

ISAPI包括ISAPI Extension和ISAPI Filter

 

ISAPI Extension

不用種類的動態資源,會有不同的ISAPI擴展.

如Asp.Net(.aspx .asmx .svc等)則為aspnet_isapi.dll。在目錄“%windir%\Microsoft.NET\Framework\{version no}\”中找到該dll。

 

ISAPI Filter

Filter則可以在HTTP請求真正被處理之前查看、修改、轉發或者拒絕請求,比如IIS可以利用ISAPI篩選進行請求的驗證(Authentication)。

 

請求Asp.Net

如果我們請求的是一個基於ASP.NET的資源:

  1. 加載aspnet_isapi.dll
  2. 創建工作進程(第一次請求)
  3. 加載CLR(第一次請求)
  4. 創建AppDomain(某個web應用的第一次請求)
  5. 執行ISAPIRuntime.

圖:應用程序環境

說明:

  1. 對於IIS 5.x來說,該工作進程為aspnet_wp.exe。
  2. aspnet_isapi.dll與工作進程之間通過命名管道(Named Pipes)進程通信,以獲得最好的性能。
  3. 對於寄宿於IIS 5.x的所有Web 應用都運行在同一個工作進程的不同AppDomain中。

 

IIS 6

IIS5的不足

  1. aspnet_isapi與工作進程之間是跨進程通信。
  2. 所有的web應用都是在同一個工作進程中。

 

IIS6解決辦法

  1. 將aspnet_ispai.dll加載到工作進程中。
  2. 建立應用程序池,一個應用程序池對應一個工作進程。

 

另外在IIS6中,創建新的http監聽器:HTTP協議棧(HTTP Protocol Stack,HTTP.SYS)

  • 持續監聽:由於HTTP.SYS是一個網絡驅動程序,始終處於運行狀態,對於用戶的HTTP請求,能夠及時作出反應;
  • 更好的穩定性:HTTP.SYS運行在操作系統內核模式下,並不執行任何用戶代碼,所以其本身不會受到Web應用、工作進程和IIS進程的影響;
  • 內核模式下數據緩存:如果某個資源被頻繁請求,HTTP.SYS會把響應的內容進行緩存,緩存的內容可以直接響應后續的請求。由於這是基於內核模式的緩存,不存在內核模式和用戶模式的切換,響應速度將得到極大的改進。

 

 

請求Asp.Net

與IIS5.X不同的是:

1.W3SVC服務根據請求創建工作進程

2.aspnet_isapi.dll是在工作進程的初始化過程中被加載。

  

 

說明:

  1. W3SVC服務已經從iis進程中脫離出來。http.sys接受到請求,將直接分發給w3svc服務
  2. 在IIS6中工作進程名為w3wp.exe
  3. 工作進程的這種創建方式被稱為請求式創建

 

IIS 7+

W3SVC服務

在IIS6中的W3SVC服務的功能

  • HTTP請求接收:接收HTTP.SYS監聽到的HTTP請求;
  • 配置管理:從元數據庫(Metabase)中加載配置信息對相關組件進行配置;
  • 進程管理:創建、回收、監控工作進程。

在IIS7中W3SVC只負責第一個功能,剩余功能交給WAS服務管理

 

WAS服務

IIS7引入Windows進程激活服務(Windows Process Activation Service,WAS):同時處理HTTP和非HTTP請求。

 

在WAS中,定義了一個重要的接口:監聽器適配器接口(Listener Adapter Interface)抽象出不同協議監聽器監聽到的請求。

WAS將監聽W3SVC服務的http請求以及WCF服務的TCP、Named Pipes、MSMQ3種請求.

 

說明

WCF提供的這3種監聽器和監聽適配器定義在程序集SMHost.exe中,你可以通過下面的目錄找到該程序集:%windir%\Microsoft.NET\Framework\v3.0\Windows Communication Foundation。

SMHost.exe提供了4個重要的Windows Service:

  • NetTcpPortSharing為WCF提供TCP端口共享,關於端口共享;
  • NetTcpActivator為WAS提供基於TCP的激活請求,包含TCP監聽器和對應的監聽適配器;
  • NetPipeActivator為WAS提供基於命名管道的激活請求,包含命名管道監聽器和對應的監聽適配器;
  • NetMsmqActivator為WAS提供基於MSMQ的激活請求,包含MSMQ監聽器和對應的監聽適配器。

 

集成模式

傳統模式的缺點

  • 相同操作的重復執行:IIS與ASP.NET之間具有一些重復的操作,比如身份驗證;
  • 動態文件與靜態文件處理的不一致:因為只有基於ASP.NET的動態文件(比如.aspx、.asmx、.svc等等)的HTTP請求才能通過ASP.NET ISAPI進入ASP.NET管道,而對於一些靜態文件(比如.html、.xml、.img等)的請求,則由IIS直接響應,那么ASP.NET管道中的一些功能將不能用於這些基於靜態文件的請求,比如,我們希望通過Forms認證應用於基於圖片文件的請求;
  • IIS難以擴展:對於IIS的擴展基本上就體現在自定義ISAPI,但是對於大部分人來說,這不是一件容易的事情。因為ISAPI是基於Win32的非托管的API,並非一種面向應用的編程接口。通常我們希望的是諸如定義ASP.NET的HttpModule和HttpHandler一樣,通過托管代碼的方式來擴展IIS。

 

集成模式

實際上IIS7集成模式,就是讓用戶可以通過編寫托管代碼的module,把托管代碼插入到IIS內核代碼中來解析,方便大家精確控制任意請求,帶來更好的擴展性。

(這里面每個靜態文件也會經過生命周期事件,執行效率肯定會有所下降.)

 

配置文件上的區別

  <!--傳統模式-->
  <system.web>
    <customErrors mode="RemoteOnly">
      <error statusCode="404" redirect="404.html"/>
      <error statusCode="500" redirect="500.html"/>
    </customErrors>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" />
  </system.web>
  <!--集成模式-->
  <system.webServer>
    <httpErrors errorMode="DetailedLocalOnly">
      <clear/>
      <error path="404.html" statusCode="404"/>
      <error path="500.html" statusCode="500"/>
    </httpErrors>
  </system.webServer>

 

Asp.Net管道

 

  1. 加載CLR:在工作進程中,ISAPI負責進行CLR的加載(如果.NET運行時尚未加載).
  2. 創建AppDomain:當成功加載了運行時后,會通過AppDomainFactory為該Web應用創建一個應用程序域(AppDomain)。
  3. 執行ISAPIRuntime的int ProcessRequest(IntPtr ecb, int iWRType)方法
  4. 執行HttpRuntime的PR方法  
  5. 獲取httpapplication實例,調用httpapplication的pr方法
  6. 觸發httpapplication各事件.

 

擴展

  1. 在HttpApplication初始化過程中,會根據配置文件加載並初始化相應的HttpModule對象。對於HttpApplication來說,在它處理HTTP請求的不同的階段會觸發不同的事件(Event),而HttpModule的意義在於通過注冊HttpApplication的相應的事件,將所需的操作注入整個HTTP請求的處理流程。ASP.NET的很多功能,比如身份驗證、授權、緩存等,都是通過相應的HttpModule實現的。
  2. 而最終完成對HTTP請求的處理實現在另一個重要的對象中:HttpHandler。對於不同的資源類型,具有不同的HttpHandler。比如.aspx頁對應的HttpHandler為System.Web.UI.Page,WCF的.svc文件對應的HttpHandler為System.ServiceModel.Activation.HttpHandler。
  3. 對於一個ASP.NET應用來說,HttpApplication派生於global.asax文件,我們可以通過創建global.asax文件對HttpApplication的請求處理行為進行定制。global.asax采用一種很直接的方式實現了這樣的功能,這種方式既不是我們常用的方法重寫(Method Overriding)或者事件注冊,而是直接采用方法名匹配。在global.asax中,我們按照這樣的方法命名規則進行事件注冊:Application_{Event Name}。比如Application_BeginRequest方法用於處理HttpApplication的BeginRequest事件。 

 

 

 

 

 

HttpModule

從功能上講,HttpModule之於ASP.NET,就好比ISAPI Filter之於IIS一樣。IIS將接收到的請求分發給相應的ISAPI Extension之前,注冊的ISAPI Filter會先截獲該請求。

如果說HttpModule相當於IIS的ISAPI Filter的話,我們可以說HttpHandler則相當於IIS的ISAPI Extension,HttpHandler在ASP.NET中扮演請求的最終處理者的角色。 

當請求轉入ASP.NET管道后,最終負責處理該請求的是與請求資源類型相匹配的HttpHandler對象,但是在Handler正式工作之前,ASP.NET會先加載並初始化所有配置的HttpModule對象。HttpModule在初始化的過程中,會將一些功能注冊到HttpApplication相應的事件中,那么在HttpApplication整個請求處理生命周期中的某個階段,相應的事件會被觸發,通過HttpModule注冊的事件處理程序也得以執行。

所有的HttpModule都實現了IHttpModule接口.

namespace System.Web
{
  public interface IHttpModule
  {
    void Init(HttpApplication context);

    void Dispose();
  }
}

 

系統定義的HttpModule

  • OutputCacheModule:實現了輸出緩存(Output Caching)的功能;
  • SessionStateModule:在無狀態的HTTP協議上實現了基於會話(Session)的狀態;
  • WindowsAuthenticationModule + FormsAuthenticationModule:實現了3種典型的身份認證方式:Windows認證、Forms認證;
  • WCFModule:使Asp.Net擴展出WCF服務(System.ServiceModel.Activation.HttpModule)

 

自定義HttpMoudle

  1. 實現IHttpMoudle
  2. 修改配置文件Web.config

 

 

 

HttpHandle

對於不同資源類型的請求,ASP.NET會加載不同的Handler來處理,也就是說.aspx page與.asmx web service對應的Handler是不同的。

所有的HttpHandler都實現了接口IHttpHandler。

  public interface IHttpHandler
  {
    bool IsReusable { get; }

    void ProcessRequest(HttpContext context);
  }

 

系統定義的HttpHandle

WebForm的aspx文件:System.Web.UI.Page

WCF的svc文件:System.ServiceModel.Activation.HttpHandler

MVC:MVCHandler

 

自定義HttpHandle

由於Handle是在PostMapRequestHandler前和 PostResolveRequestCache 后映射指定的Handle,

所以我們可以在PostResolveRequestCache事件中注冊我們的Handle.

PreRequestHandlerExecute 后將會調用我們的Handle.PR方法.  

 

 

 

擴展

HttpApplication主要有19個事件,通過我的網站任意地址+參數即可訪問所有事件。

+?pipe可以查看這些事件觸發時間.如:http://neverc.cn?pipe

+?pe可以附帶我的網站內容:http://neverc.cn?pe

猜猜如何實現出以上效果

 

本文地址:http://neverc.cnblogs.com/p/4807836.html

本文參考:  http://www.cnblogs.com/artech/archive/2009/06/20/1507165.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM