技术文章

了解最新技术文章

当前位置:首页>技术文章>技术文章
全部 7 常见问题 0 技术文章 7

IIS/ASP.NET 管道

时间:2022-10-13   访问量:1032

  ASP.NET MVC 是建立在 ASP.NET 平台上基于 MVC 模式的 Web 应用框架,深刻理解 ASP.NET MVC 的前提是对 ASP.NET 对管道设计有着深刻的理解。由于 ASP.NET Web 大多数应用程序都是寄宿的 IIS 上两者结合起来理解 IIS 和 ASP.NET 如何在管道中流动。

  IIS5.x 是如何处理基于 ASP.NET 资源(如.aspx、.a ** x...)请求的呢?

  IIS5.x运行在进程 InetInfo.exe 在这个过程中,有一个名字叫做 World Wide Web Publishing Service(简称W3SVC)的 Windows 服务。W3SVC 主要负责 HTTP 监控、激活、管理过程、加载配置(从 Metabase 加载相关配置信息)等。

  当检测到某个 HTTP 请求时,IIS 静态资源或动态资源首先根据扩展名称来判断。静态资源 IIS 文件内容将直接响应给客户端,动态资源将通过扩展名从 IIS 的脚本映射(Script Map)找到相应的ISAPI 动态链接库(Dynamic Link Library, DLL)。

  ISAPI(Internet Server Application Programming Inte ** ce)是本地的(Native)Win32 API,是 IIS 和其他动态 Web 应用程序或平台之间的链接。

  ISAPI 动态链接库的定义(DLL)文件中, ASP.NET ISAPI 对应的 DLL 文件名称为 aspnet_isapi.dll,位于 %windir%Microsoft.NETFramework{version no}中。

  ISAPI 支持 ISAPI 扩展(ISAPI Extension)和 ISAPI 筛选(ISAPI Filter),真正处理前者 HTTP 请求界面,后者可以在 HTTP 查看、修改、转发、拒绝真正处理前的请求,如 IIS 可利用 ISAPI 筛选验证要求。

  若要求是基础 ASP.NET 资源类型,如.aspx、.a ** x、.svc等,aspnet_isapi.dll 会被加载,ASP.NET ISAPI 随后会创建 ASP.NET 工作过程(如果还没有开始)。对于 IIS5.x 工作流程为 aspnet.exe。IIS 命名过程和工作过程之间的管道(Named Pipes)进行通信。

  在工作过程的初始化过程中,.NET 运行时(CLR)它将被加载以建立一个托管环境。对于某个 Web 应用程序的初始要求,CLR 会被其创建一个应用程序域(Application Do ** in)。

  在应用程序域中,HTTP 运行时(HTTP Runtime)加载并用于创建相应的应用程序。 IIS5.x 的所有Web应用程序在同一过程中运行(工作过程) aspnet_wp.exe)不同的应用程序域。

  IIS5.x有两个缺点:

  解决方案:IIS6.0将ISAPI动态链接库直接加载到工作过程中

  解决方案:IIS6.0 加入应用程序池 Application Pool 一个或多个机制 Web 创建一个应用程序池,每个应用程序池对应一个独立的工作过程 w3wp.exe,因此,在不同的应用程序池中运行 Web 应用程序提供基于工艺水平的隔离机制。

  IIS6.0 最重要的是创建一个名字 HTTP.SYS 的 HTTP 监听器,HTTP.SYS 以驱动程序的形式运行Windows 的内核模式 Kernal Mode下,它是 Windows TCP/IP 网络子系统的一部分属于结构 TCP 以上网络驱动程序。

  严格地说,HTTP.SYS 已经不属于 IIS 所以 HTTP.SYS 未保存配置信息 IIS 的元数据库Metabase,但在注册表中定义。HTTP.SYS 注册表项的路径为HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/HTTP。

  HTTP.SYS能带来以下好处:

  由于 HTTP.SYS 它是一个网络驱动程序,总是处于运行状态,所以对于用户会议 HTTP 请求可以及时响应。

  HTTP.SYS 在操作系统内核模式下运行,不执行任何用户代码,不会受到影响 Web应用、工作流程、IIS影响过程。

  如果某个资源被频繁请求,HTTP.SYS 缓存响应内容,缓存内容可直接响应后续请求。由于这是基于核模式的缓存,没有核模式和用户模式之间的切换,响应速度大大提高。

  与 IIS5.x 不同,W3SVC 在 IIS6.0 中从 InetInfo.exe 脱离过程,对 IIS6.0 来说,InetInfo.exe基本上可以看作是简单的 IIS 管理过程,在另一个过程中运行 SvcHost.exe中。不过 W3SVC 基本功能没有改变,只是在功能实现上做了相应的改进。与 IIS5.x 同样,元数据库 Metabase 依然存在于InetInfo.exe进程中。

  当监听到HTTP请求时,HTTP.SYS 将其分发给 W3SVC,W3SVC 对请求进行分析 URL ,并根据从 Metabase 获取的 URL 与 Web 目标应用将应用程序之间的映射关系程序之间的映射关系。若工作过程不存在或尚未创建或回收,则需要创建新的工作过程。在工作过程的初始化过程中,相应的 ISAPI 加载动态链接库 ASP.NET 对于应用,加载 ISAPI.dll 为 aspnet_isapi.dll。ASP.NET ISAPI 负责进行 CLR 创建和加载应用程序域 Web 应用程序的初始化等操作。

  IIS7.0创新了要求的监控和分配机制,体现在介绍上Windows过程激活服务(Windows Process Activation Service, WAS),分流了原来IIS6.0中W3SVC部分部分功能。

  IIS6.0中的W3SVC主要承载以下三个功能:

  IIS7.后两组功能组功能WAS中,但接收HTTP要求的任务仍然存在W3SVC上。WAS的引入为IIS7.0提供了对非HTTP通过监控适配器接口支持协议 Listener Adapter Inte ** ce对不同协议的监听器进行抽象。具体来说,除了专门用于监控外,HTTP请求的HTTP.SYS之外,WAS利用TCP监名管道监听器和监听器M ** Q监听器提供基础TCP、命名管道、M ** Q监控支持传输协议。

  与这三个监听器相对应的是三个监听适配器,它们提供监听器WAS从这个意义上说,监听适配器接口之间的适配,IIS7.0中的W3SVC相当于HTTP.SYS监听适配器。这3种非HTTP程序集中定义监听器和监听适配器 ** SvcHost.exe 中。可在目录%windir%Microsoft.NETFrameworkv3.0Windows Communication Foundation中找到。

  从程序集所在的目录名称可以看出,这三种监听器/监听适配器是为了WCF设计,他们以Windows以服务的形式工作。虽然定义为程序集中。但是,它仍然可以通过服务工作管理器单独启动、终止和配置。一般来说, ** SvcHost.exe提供四个重要的Windows Service。

  无论是从W3SVC接收到的HTTP请求,或通过WCF监听适配器收到的其他传输协议的请求最终被传递到WAS。如果相应的工作进程,针对单个应用程序池尚未创建,则WAS会创建工作流程。WAS相关配置信息在请求处理过程中通过内置配置管理模块加载,相关组件配置。

  与IIS5.x和IIS6.0基于Metabase不同的配置信息存储,IIS7.大部分存储配置信息XML基本配置存储在形式配置文件中 applicationHost.config 中。

  从IIS5.x和IIS6.0中不难发现,IIS与ASP.NET是两条独立的管道 Pipeline。在各自的管辖范围内,各有各自的机制HTTP请求处理。两条管道通过ISAPI实现连通。IIS是第一道屏障,当对HTTP要求进行必要的早期处理,如身份认证等。IIS通过ISAPI分发请求ASP.NET管道。当ASP.NET在自己的管道范围内完成HTTP处理请求时,处理结果返回IIS,IIS日志记录、压缩等后期处理。之后生成HTTP回复响应请求。

  另一方面,IIS运行在非托管的环境中,而ASP.NET管道是托管的,所以ISAPI是连接非托管环境和托管环境的纽带。IIS5.x和IIS6.将两条管道隔离的局限性在于:

  IIS和ASP.NET有一些重复的操作,如身份验证。

  因为只有基础ASP.NET 动态文件的HTTP请求只能通过ASP.NET ISAPI进入ASP.NET管道对静态文件的要求由管道决定IIS直接响应,然后ASP.NET基于静态文件的要求,如通过Forms基于图片文件的要求不能进行认证应用。

  对于IIS基本上提到了自定义的扩展ISAPI,对大多数人来说,这并不容易,因为ISAPI是基于Win32的非托管的API,它不是一个面向应用程序的编程接口。通常想要的是定义ASP.NET的HttpModule和HttpHandler同样,扩大托管的方式也是如此。IIS。

  对于Windows平台下的IIS来讲,ASP.NET无疑是一等公民,IIS7.实现了两者的集成,通过集成可以获得以下好处:

  这些IIS Module注册到IIS通过通用的请求处理管道IIS Module无论基于什么样的资源类型,组成的管道都可以处理所有的要求。例如,可以FormAuthenticationModule提供的Forms基于认证的应用 .aspx、CGI请求和静态文件。

  比如将ASP.NET的URL在身份验证前重写功能

  比如Module、Handler错误配置的映射和定制 Custom Error Configuration 等

  以 IIS6.以0为例,它的工作过程 w3wp.exe 中会利用 aspnet_isapi.dll 加载 .NET 运行时(如果 .NET 运行时尚未加载)。IIS6.0引入了应用程序池的概念,工作过程对应于应用程序池。可以携带一个或多个应用程序池Web应用,每个Web应用映射到一个IIS虚拟目录,和IIS5.x一样,每个Web应用程序在各自的应用程序域中运行。

  如果HTTP.SYS接收到的HTTP请求是对该 Web 在成功加载运行后,第一次访问应用程序,IIS会通过 AppDo ** inFactory 为该Web创建应用程序域的应用程序。然后是一个特殊的操作时间 IsapiRuntime 被加载。IsapiRuntime 在程序集中定义 System.Web.dll在中间,相应的命名空间是System.Web.Hosting, 被加载的 IsapiRuntime 会接管该HTTP请求。

  接管 HTTP 请求的 IsapiRuntime 会先创建一个 IsapiWorkerRequest 包装当前物体HTTP请求后,将次对象传递给 ASP.NET 运行时 HttpRuntime。从此时起, HTTP请求正式进入ASP.NET管道。HttpRuntime会根据 IsapiWorkerRequest 对象的对象创建是用来表示当前的对象HTTP请求的上下文 Context 对象 HttpContext。

  随着 HttpContext 的创建,HttpRuntime 会利用 HttpApplicationFactory 创造新的或获得现有的 HttpApplication 对象。实际上 ASP.NET 维护着一个 HttpApplication 对象池, HttpApplicationFactory 从池中选取可用的 HttpApplication 用于处理 HTTP 请求,处理完毕后将其释放到对象池中。HttpApplication 负责处理当前的 HTTP 请求。

  在 HttpApplication 初始化过程中,ASP.NET 会根据配置文件加载并初始化注册的 HttpModule 对象。对于 HttpApplication 来说,在它处理HTTP请求的不同阶段会触发不同的事件 Event,而HttpModule的意义在于通过注册HttpApplication的相应事件,将所需的操作注入整个HTTP请求的处理流程。ASP.NET的很多功能都是通过相应的HttpModule实现的。

  最终完成对HTTP请求的处理实现在HttpHandler中,不同的资源类型对应着不同类型的HttpHandler。比如.aspx页面对应的HttpHandler类型为System.Web.UI.Page,WCF的.svc文件对应的HttpHandler类型为System.ServiceModel.Activation.HttpHandler。

  HttpApplication 是整个 ASP.NET 基础架构的核心,负责处理分发给它的HTTP请求。由于一个HttpApplication对象在某个时刻只能处理一个请求,只有完成对某个请求的处理后才能用于后续请求的处理,所以ASP.NET采用对象池的机制来创建或获取 HttpApplication 对象。

  当第一个请求抵达时,ASP.NET会一次创建多个HttpApplication对象,并将其置于池中,然后选择其中一个对象来处理该请求。处理完毕后,HttpApplication不会被回收,而是释放到池中。对于后续的请求,空闲的 HttpApplication 对象会从池中取出。如果池中所有的 HttpApplication 对象都处于繁忙的状态,在没有超出 HttpApplication 池最大容量的情况下,ASP.NET 会创建新的HttpApplication对象,否则将请求放入队列等待现有HttpApplication的释放。

  HttpApplication 处理请求的整个生命周期是一个相对复杂的过程,在该过程的不同阶段会触发相应的事件。可注册相应的事件,将处理逻辑注入到HttpApplication处理请求的某个阶段。

  HttpApplication在处理每个请求时触发的事件

  BeginRequestHTTP管道开始处理请求时,会触发BeginRequest事件。

  AuthenticateRequest, PostAuthenticateRequestASP.NET 先后触发这两个事件,使安全模块对请求进行身份验证。

  AuthorizeRequest, PostAuthorizeRequestASP.NET先后触发这两个事件,使安全模块对请求进行授权。

  ResolveRequestCache, PostResolveRequestCacheASP.NET 先后触发这两个事件,以使缓存模块利用缓存的内容对请求直接进行响应(缓存模块可将响应内容进行缓存,对于后续的请求,直接将缓存的内容返回,从而提高响应能力。)

  PostMapRequestHandler对于访问不同资源类型,ASP.NET具有不同的HttpHandler对其进行处理,对于每个请求,ASP.NET会通过扩展名选择匹配响应的HttpHandler类型,成功匹配后,该事件被触发。

  AcquireRequestState, PostAcquestRequestStateASP.NET先后触发这两个事件,使状态管理模块获取基于当前请求相应的状态,如SessionState。

  PreRequestHandlerExecute、PostRequestHandlerExecuteASP.NET 最终通过与请求资源类型相对应的 HttpHandler 实现对请求的处理,在实行 HttpHandler 前后,这两个事件被先后触发。

  ReleaseRequestState、PostReleaseRequestStateASP.NET 先后触发这两个事件,使状态管理模块释放基于当前请求响应的状态。

  UpdateRequesetCache、PostUpdateRequestCacheASP.NET先后触发这两个事件,以使缓存模块将HttpHandler处理请求得到的内容得以保存到输出缓存中。

  LogRequest、PostLogRequestASP.NET先后触发这两个事件为当前请求进行日志记录

  EndRequest 整个请求处理完成后,EndRequest事件会触发。

  对于一个ASP.NET应用来说,HttpApplication派生于Global.asax文件,通过创建Global.asax文件对HttpApplication的请求处理行为进行定制。Global.asax采用一种很直接的方式实现了这样的功能,这种方式不是方法重写或事件注册,而是直接采用方法名匹配。在Global.asax中按照“Application_{Event Name}”的命名规则进行事件注册。

  ASP.NET拥有一个具有高度的可扩展的引擎,能处理不同资源类型的请求,HttpModule是功不可没的。

  当请求转入ASP.NET管道时,最终负责处理该请求的是与请求资源类型相匹配的HttpHandler对象,但是在HttpHandler正式工作之前。ASP.NET会先加载并初始化所有配置的HttpModule对象。HttpModule在初始化过程中,会将一些回调操作注册到HttpApplication相应的事件中。在HttpApplication请求处理生命周期中的某个阶段,相应的事件会被触发,通过HttpModule注册的事件处理程序也得以执行。

  所有的HttpModule都实现了具有如下定义的System.Web.IHttpModule接口,其Init方法实现了针对自身的初始化。该方法接受一个HttpApplication对象,有了这个对象,事件注册就很容易了。

  ASP.NET提供了很多基础功能是通过相应的HttpModule实现的。除了系统定义的HttpModule之外,可自定义HttpModule,通过 Web.config 可很容易地将其注册到 Web 应用中。

  对于不同资源类型的请求,ASP.NET会加载不同的Handler来处理,比如.aspx页面与.a ** x Web服务对应的Handler是不同的。

  所有的HttpHandler都实现了具有如下定义的接口 System.Web.IHttpHandler,定义其中的方法ProcessRequest提供了处理请求的实现。

  另一个代表异步版本的HttpHandler的IHttpAsyncHandler接口继承自IHttpHandler,它通过调用BeginProcessRequest/EndProcessRequest方法以异步的方式处理请求。

  某些 HttpHandler 具有一个与之相关的HttpHandlerFactory,后者实现了具有如下定义的接口 System.Web.IHttpHandlerFactory,定义其中的方法GetHandler用于创建新的HttpHandler或获取已经存在的HttpHandler。

  HttpHandler和HttpHandlerFactory的类型都可以通过相同的方式配置到 Web.config中。

  在调用当前HttpContext的Re ** pHandler方法时指定一个具体的HttpHandler对象,是为了让ASP.NET直接跳过默认的HttpHandler映射操作。此外,由于这个默认的HttpHandler映射发生在HttpApplication的PostMapRequestHandler事件触发之前,所以只有在这之前调用Re ** pHandler方法才有意义。

上一篇:ASP.NET开发实战-(1)VS创建一个ASP.NET Web程序

下一篇:Asp.net 怎样从入门到精通?

发表评论:

评论记录:

未查询到任何数据!

在线咨询

点击这里给我发消息 售前咨询专员

点击这里给我发消息 售后服务专员

在线咨询

免费通话

24小时免费咨询

请输入您的联系电话,座机请加区号

免费通话

微信扫一扫

微信联系
返回顶部