- ·上一篇文章:使用更精简的代码保证ASP.NET应用程序的安全
- ·下一篇文章:ASP.Net中自定义Http处理及应用之HttpHandler篇
ASP.NET HTTP运行时组成详解
简介
不管使用哪种底层平台,可靠性和性能都是对所有Web应用程序的主要要求,尽管从某种意义上讲,这两个要求是相互矛盾的。例如,要构建更可靠、更健壮的应用程序,可能需要将Web服务器与具体的应用程序分离,使应用程序在进程外工作。但是,如果在不同于Web服务器进程的内存环境中工作,应用程序将变慢。因此,需要采取合理的措施,以确保进程外代码尽可能快地运行。
在构建Microsoft?ASP.NET运行时环境时,依据的设计原则即:充分考虑可靠性和性能。得到的ASP.NET进程模型包含了两个系统元素-一个存在于Web服务器进程中的进程内连接器,一个外部的辅助进程。另外,ASP.NET运行时结构的可伸缩能力很强,可以自动使用多处理器硬件中任意选定的处理器。这种模式被称为“WebGarden”,它可以使多个辅助进程同时运行,而且各个进程均在独立的处理器中。
高度概括起来,ASP.NET运行时具有三大属性:
应用程序和ASP.NET辅助进程之间完全分离。提供服务的辅助进程的寿命决不会影响应用程序的寿命。换句话说,当应用程序启动并处于运行状态时,辅助进程可以随时终止。
尽管ASP.NET应用程序从不在Web服务器内采用进程内的方式运行,但大多数情况下,其总体性能仍接近于进程内应用程序的性能。
为WebGarden体系结构提供了内置的和可配置的支持。只要简单检查一下配置文件中的设置,辅助进程就可以克隆自己,以利用所有与进程密切相关的CPU。因此,在大多数情况下,您在具备多处理器的计算机中获得的可缩放性将呈线性增长的趋势。(本文后面将详细介绍此内容。)
本文将介绍ASP.NET运行时环境的组成元素,然后一步一步地讲述从URL请求变为纯HTML文本的“漫长而曲折”的过程。
除非另有说明,否则以下介绍中均指ASP.NET的默认进程模型,即Microsoft?InternetInformationServices(IIS)5.x中唯一的模型。
ASP.NET结构的组件
执行ASP.NET应用程序需要宿主Web服务器的支持。在Microsoft?Windows?的Server平台中,Web服务器由名为inetinfo.exe的IIS可执行文件表示。Windows2000及以上版本的操作系统本身均提供了Web服务器。但需要注意,在Microsoft?WindowsServer2003中,并未默认安装IIS和ASP.NET,必须通过单击“控制面板”中的“添加或删除程序”小程序将其添加到系统中。
IIS是一个未托管的可执行程序,它提供了一个基于ISAPI扩展模块和筛选器模块的可扩展模型。通过编写此类模块,开发人员可以直接管理对特定资源类型的请求,并在各个预定义的步骤中接收当前请求。扩展和筛选器是一些DLL,可以导出一些具有已知名称和签名的函数。这些插件组件是在IIS配置数据库中注册并配置的。
只有少数几种被客户端请求的资源类型由IIS直接处理。例如,对HTML页面、文本文件、JPEG和GIF图像的传入请求由IIS处理。对ActiveServerPage(*.asp)文件的请求通过调用名为asp.dll的ASP专用扩展模块进行解析。同样,对ASP.NET资源(例如,*.aspx、*.asmx、*.ashx)的请求将传递到ASP.NETISAPI扩展。该系统组件是一个名为aspnet_isapi.dll的Win32DLL。ASP.NET扩展可以处理多种资源类型,包括Web服务和HTTP处理程序调用。
ASP.NETISAPI扩展是一个Win32DLL,未集成托管代码。它是接收和分派对各种ASP.NET资源的请求的控制中心。按照设计,该模块存在于IIS进程中,在具有管理员权限的SYSTEM帐户下运行。开发人员和系统管理员不能修改此帐户。ASP.NETISAPI扩展负责调用ASP.NET辅助进程(aspnet_wp.exe),而该进程又负责控制请求的执行。除了对请求进行安排以外,ASP.NETISAPI还监视辅助进程的运行情况,并在性能降低到一定程度时将进程取消。
辅助进程是一小段Win32shell代码,集成了公共语言运行库(CLR)并运行托管代码。它负责处理对ASPX、ASMX和ASHX资源的请求。一般来说,此进程在一台给定的计算机中只有一个实例。所有当前激活的ASP.NET应用程序均在其中运行,每个应用程序都位于一个独立的AppDomain中。但是,如前所述,辅助进程支持WebGarden模式,即进程的相同副本都运行在与进程密切相关的CPU中。(更多内容,请参阅本文后面的“WebGarden模型”部分。)
ISAPI和辅助进程之间的通讯是使用一组命名管道进行的。命名管道是一种Win32机制,用于跨进程边界传输数据。顾名思义,命名管道的工作方式与管道相似:在一端输入数据,在另一端输出相同的数据。建立的管道既可以连接本地进程,也可以连接远程计算机上运行的进程。对于本地进程间通讯,管道是Windows中的最有效、最灵活的工具。
为确保获得最优性能,aspnet_isapi使用异步命名管道来将请求转发给辅助进程并获得响应。另一方面,辅助进程在需要查询有关IIS环境的信息(即服务器变量)时又使用同步管道。aspnet_isapi模块创建固定数量的命名管道,并使用重叠的操作以通过小的线程池处理同一时间进行的连接。当通过管道进行的数据交换操作结束后,完成例程将断开客户端,并重新使用管道实例为新的客户端服务。线程池和重叠操作均可以保证使ASP.NETISAPI的性能达到令人满意的水平。但是,aspnet_isapi扩展决不会处理HTTP请求。
ASP.NET请求的处理逻辑可以概括为以下步骤:
当请求到达时,IIS检查资源类型并调用ASP.NETISAPI扩展。如果启用了默认的进程模型,aspnet_isapi会将请求排队,并将请求分配给辅助进程。所有的请求数据都通过异步I/O发送。如果启用了IIS6进程模型,请求将自动在辅助进程(w3wp.exe)中排队,此辅助进程用于处理应用程序所属的IIS应用程序池。IIS6辅助进程不了解ASP.NET和托管代码的任何情况,它只是处理*.aspx扩展并加载aspnet_isapi模块。当ASP.NETISAPI在IIS6进程模型中运行时,它的工作方式有所不同,仅在w3wp.exe辅助进程的上下文中加载CLR。
收到请求后,ASP.NET辅助进程将通知ASP.NETISAPI,它将为请求服务。通知通过同步I/O实现。之所以使用同步模型,是因为请求只有在ISAPI内部请求表中被标记为“executing”,辅助进程才能开始处理它。如果请求已经由特殊的辅助进程进行处理,则不能再将它指定到其他进程,除非原始进程已取消。
在辅助进程的上下文中执行请求。有时,辅助进程可能需要回调ISAPI以完成请求,也就是需要说枚举服务器变量。这种情况下,辅助进程将使用同步管道,因
