WCF技术剖析之二:再谈IIS与ASP.NET管道2012-10-08 cnblogs ArtechIIS 5.x与ASP.NET我们先来看看IIS 5.x是如何处理基于ASP.NET资源(比如.aspx,.asmx等)请求的,整个过程基本上可以通过图1体现。IIS 5.x运行在进程InetInfo.exe中,在该进程中一个最重要的服务就是名为World Wide Web Publishing Service(简称W3SVC)的Windows Service。W3SVC的主要功能包括HTTP请求的监听、工作进程的管理以及配置管理(通过从Metabase中加载相关配置信息)等。当检测到某个HTTP Request后,先根据扩展名判断请求的是否是静态资源(比如.html,.img,.txt,.xml等),如果是则直接将文件内容以HTTP Response的形式返回。如果是动态资源(比如.aspx,asp,php等等),则通过扩展名从IIS的脚本影射(Script Map)找到相应的ISAPI Dll。

图1 IIS 5.x与ASP.NETISAPI是Internet服务器API(Internet Server Application Programming Interface)的缩写,是一套本地的(Native)Win32 API,具有较高的执行性能,是IIS和其他动态Web应用或者平台之间的纽带。比如ASP ISAPI桥接IIS与ASP,而ASP.NET ISAPI则连接着IIS与ASP.NET。ISPAI定义在一个Dll中,ASP.NET ISAPI对应的Dll为Aspnet_isapi.dll,你可以在目录“%windir%Microsoft.NETFramework{version no}”中找到该Dll。ISAPI支持ISAPI扩展(ISAPI Extension)和ISAPI筛选(ISAPI Filter),前者是真正处理HTTP请求的接口,后者则可以在HTTP请求真正被处理之前查看、修改、转发或者拒绝请求,比如IIS可以利用ISAPI筛选进行请求的验证(Authentication)。如果我们请求的是一个基于ASP.NET的资源类型,比如:.aspx Web Page、 .asmx Web Service或者.svc WCF Service等,Aspnet_isapi.dll会被加载,ASP.NET ISAPI扩展会创建ASP.NET的工作进程(如果该进程尚未启动),对于IIS 5.x来说,该工作进程为aspnet.exe。IIS进程与工作进程之间通过命名管道(Named Pipes)进程通信,以获得最好的性能。在工作进程初始化过程中,.NET 运行时(CLR)被加载,从而构建了一个托管的环境。对于某个Web应用的初次请求,CLR会为其创建一个AppDomain。在此AppDomain中,HTTP运行时(HTTP Runtime)被加载并用以创建相应的应用。对于寄宿于IIS 5.x的所有Web 应用都运行在同一个进程(工作进程Aspnet_wp.exe)的不同AppDomain中。IIS 6与ASP.NET通过上面的介绍,我们可以看出IIS 5.x至少存在着如下两个方面的不足:ISAPI Dll被加载到InetInfo.exe进程中,它和工作进程之间是一种典型的跨进程通信方式,尽管采用性能最好的命名管道,但是仍然会带来性能的瓶颈;所有的ASP.NET应用,运行在相同的进程(aspnet_wp.exe)中的不同的应用程序域(AppDomain)中,基于应用程序域的隔离级别不能从根本上解决一个应用程序对另一个程序的影响,在更多的时候,我们需要不同的Web应用运行在不同的进程中。在IIS 6.0中,为了解决第一个问题,ISAPI.dll被直接加载到工作进程中。为了解决第2个问题,引入了应用程序池(Application Pool)的机制。我们可以为一个或者多个Web应用创建应用程序池,每一个应用程序池对应一个独立的工作进程,从而为运行在不同应用程序池中的Web应用提供基于进程的隔离级别。IIS 6.0的工作进程名称为w3wp.exe。当然,除了上面两点改进之外,IIS 6.0还有其他一些值得称道的地方,其中最重要的一点就是创建了一个新的HTTP监听器:HTTP协议栈(HTTP Protocol Stack,HTTP.SYS)。HTTP.SYS运行在Windows的内核模式(Kernel Mode)下,作为驱动程序而存在。它是Windows 2003的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会把响应的内容进行缓存,缓存的内容可以直接响应后续的请求。由于这是基于内核模式的缓存,不存在内核模式和用户模式的切换,响应速度将得到极大的改进。图2体现了IIS的结构和处理HTTP请求的流程。从中可以看出,与IIS 5.x不同,W3SVC从InetInfo.exe进程脱离出来(对于IIS6.0来说,InetInfo.exe基本上可以看作单纯的IIS管理进程),运行在另一个进程SvcHost.exe中。不过W3SVC的基本功能并没有发生变化,只是在功能的实现上作了相应的改进。与IIS 5.x一样,元数据库(Metabase)依然存在于InetInfo.exe进程中。

图2 IIS 6与ASP.NET当HTTP.SYS监听到用户的HTTP请求后,将其分发给W3SVC。W3SVC解析出请求的URL,并根据从Metabase获取的URL与Web应用之间的映射关系得到目标应用,并进一步得到目标应用运行的应用程序池或者工作进程。如果工作进程不存在(尚未创建或者被回收),则为该请求创建新的工作进程,工作进程的这种创建方式被称为请求式创建。在工作进程的初始化过程中,相应的ISAPI.dll被加载,对于ASP.NET应用来说,被加载的ISAPI.dll为Aspnet_ispai.dll。ASP.NET ISAPI再负责进行CLR的加载、AppDomain创建、Web Application的初始化等。