Windows操作系统中的IIS负责提供互联网服务,一台运行了IIS的计算机可以看成是一台Web服务器。
Windows XP SP2 中IIS主版本号为5,Windows 2003 Server为6,Vista和Windows Server 2008为7。对于Windows 2003 Server,其默认支持的ASP.NET版本为1.1,因此必须单独安装.NET Framework 2.0以上版本[1]。
目前,IIS 6是使用最为广泛的版本,IIS 5已基本不在Web服务器上部署, IIS 6与IIS 5相比在系统架构上有着较大的差异,IIS 7与IIS 6相比,基本架构并没有根本性的变化,但在许多方面有新的增强和改进。本书选择IIS 6/7进行介绍,大部分内容也适合于IIS 5,但IIS 5一些已过时的特性就不介绍了。
首先,我们来仔细分辨一下三个很容易混淆的基本概念。
8.1.1网站、Web应用程序和虚拟目录
在IIS中可以创建网站、Web 应用程序和虚拟目录,以便与计算机网络上的用户共享信息。“网站”、“Web 应用程序”和“虚拟目录”这三个概念的关系如图 8?1所示。
图 8?1 网站,应用程序与虚拟目录
简而言之,一个“网站(Web Site)”包含一个或多个“ Web 应用程序(Web Application)”,一个Web应用程序包含一个或多个“虚拟目录(Virtual Directory)”,而虚拟目录则映射到 Web 服务器或远程计算机上的物理目录。
图 8?2所示为运行IIS 7的一个Web服务器。
图 8?2 IIS 7中的网站,应用程序与虚拟目录
图 8?2中可以清楚地看到此Web服务器上有两个“网站”:Default Web Site和NewWebSite,其中Default Web Site网站中有三个“Web 应用程序”:HappyBookShopService、HappyBookShopWebSite和OnlineAlbum。而HappyBookShopWebSite应用程序下的每一个子文件夹都是一个“虚拟目录”。最顶层的虚拟目录称为“根虚拟目录”, 图 8?2中Web应用程序HappyBookShopWebSite的根虚拟目录为“/HappyBookShopWebSite”。
下面逐个剖析这三个概念。
1网站(Web Site)
网站是 Web 应用程序的容器,每个网站都有一个唯一的标识,这一标识由它的 IP 地址、端口和可选的主机头/主机名组合而成,Web服务器根据收到的HTTP请求中的这些信息来确定是对哪一个网站的请求。
在IIS 7中,将网站标识称为“网站绑定”,图 8?3所示为IIS 7默认网站的“网站绑定”对话框。
图 8?3 IIS7.0中的网站绑定
2 Web 应用程序(Web Application)
Web 应用程序是一种在应用程序池(Application Pool)[3]中运行并通过 HTTP 协议向用户提供信息服务(通常以HTML 格式表达信息)的软件程序。创建 Web 应用程序时,Web 应用程序的名称将成为网站 URL 的一部分,用户可以通过 Web 浏览器发出针对该 URL的HTTP请求。
使用Visual Studio创建的“ASP.NET网站”,其实是一个“Web 应用程序”,它并不等于IIS中的“网站”。
在 IIS中,每个网站至少必须拥有一个 Web 应用程序(但不一定是ASP.NET应用程序,可以是其他类型的Web应用程序),它被称为“根Web 应用程序”或“默认 Web 应用程序”,除此之外,网站还可以包含一个或多个ASP.NET(或其他种类) Web 应用程序。
在Windows XP SP2中,使用Visual Studio创建的ASP.NET网站发布到本机IIS之后都是作为本机默认网站(即“localhost”所代表的网站)所承载的Web应用程序而运行的。
Windows Server和Vista可以为某个ASP.NET应用程序创建一个独立的IIS网站,此网站只承载这个唯一的ASP.NET应用程序,并且运行在一个独立的应用程序池中。许多商业网站都采用这种方法以获取较高的性能,同时将此网站与Web服务器上承载的其他网站相互隔离,以增强Web服务器的安全性。
3 虚拟目录(Virtual Directory)
虚拟目录是在 IIS 中指定并映射到本地或远程服务器上的物理目录的目录名称。然后,此虚拟目录名称将成为 Web 应用程序 URL 的一部分,用户可以通过 Web 浏览器向IIS请求访问此URL所对应的物理目录中的资源。
在 IIS中,每个 Web 应用程序都必须拥有一个最顶层的虚拟目录,它被称为“根虚拟目录”。
在Visual Studio中,可以在属性窗口中直接设定ASP.NET网站的根“虚拟路径”(图 8?4)。
图 8?4 ASP.NET网站的虚拟路径
但要注意,这里设定的“虚拟路径”是Visual Studio自带的轻量级Web服务器“ASP.NET Development Server”的虚拟路径,而非IIS中的虚拟路径。如果使用Visual Studio完整版本(比如团队开发版),则可以使用一个“发布网站”的功能。在使用此功能发布网站时可以直接指定ASP.NET应用程序在IIS中所对应的根虚拟目录图8?5)。
图 8?5 设定IIS中ASP.NET网站的根虚拟目录
图 8?5中将ASP.NET网站所对应的IIS根虚拟目录设为MyNewWebSite。
一个Web 应用程序可以拥有多个虚拟目录,这些虚拟目录都将成为Web 应用程序根虚拟目录的子目录。
可以很方便地在IIS中创建一个虚拟目录(图 8?6)。
图 8?6 在IIS 7中创建一个虚拟目录
给Web应用添加完虚拟目录之后,可以通过以下URL访问虚拟目录中的网页
http://网站名称/Web应用程序根虚拟目录/新创建的子虚拟目录/Web网页名称
在上面的例子中,Web应用程序根虚拟目录为“/MyNewWebSite”,新加的虚拟目录为“MyNewVirtualDir”,它指向“D:/MyDir”目录。现假设D:/MyDir目录中有一个ASP.NET网页(不妨设为Sample.aspx),则通过以下URL可以访问此网页:
http://localhost/MyNewWebSite/MyNewVirtualDir/Sample.aspx
[1] 建议在Windows 2003 Server上安装最新版本的.NET Framework以支持一些新技术,比如AJAX和Silverlight。
[2] 更具体来说,是Windows Server的一个系统核心组件:HTTP.SYS负责这一工作。后面在介绍IIS架构时还将介绍HTTP.SYS组件。
[3]后文将应用程序池作更详细的介绍
[4]“虚拟目录”有时又被称为“虚拟路径”,两者代表同一概念。
[5]对于Visual Web Developer速成版,它没有提供“发布网站”的功能,但可以在“复制网站”对话窗口找到相应的按钮完成这一工作。或者更直接些,直接使用IIS管理器来完成这一工作。
[6]在IIS 5/6中使用“虚拟目录创建向导”来创建虚拟目录,其方法是在IIS的某个Web应用程序节点上右击,从快捷菜单中选“新建”-->“虚拟目录”命令。IIS 7的操作是类似的,但它直接在快捷菜单的第一级中就提供了“添加虚拟目录”的命令。
8.1.2 应用程序池与工作者进程
“应用程序池(Applicaion Pool)”是Windows Server为提升Web服务的性能和可靠性而引入的一个Web程序隔离机制。
一个应用程序池可包含一个或多个Web应用程序。ASP.NET Web应用程序必须运行在一个应用程序池中。
在Windows Server中,一个或多个“工作者进程(Worker Process)”为应用程序池提供服务,停止一个应用程序池将导致这些工作者进程被关闭,这时,所有发往此应用程序池中Web应用程序的HTTP请求将收到“503服务不可用”的响应信息。
图 8?7展示了一台Web服务器上正在运行的应用程序池。
图 8?7 IIS 7中的应用程序池
如图 8?7所示,本台Web服务器上的设置了3个应用程序池,每个应用程序池中可运行多个Web应用程序,图中DefaultAppPool这一应用程序池运行了5个Web应用程序。每个应用程序池都可以加载特定版本的.NET Framework,以对ASP.NET应用程序提供支持。在IIS 7中,应用程序池有两种运行模式——经典模式和集成模式。
经典模式下,IIS7应用程序池运行方式同IIS 6 [1]。
集成模式下,IIS 7直接预装载.NET Framework,从而为ASP.NET应用程序提供了更好的性能。
在IIS管理器中可以随时启动和停止某个应用程序池。
Windows Server上运行应用程序池的系统帐号是“NetworkService”。在后面的章节中可以看到在部署ASP.NET网站时往往需要给此帐号设置特定的权限(比如允许ASP.NET应用程序向某文件夹中添加文件)。
下面深入介绍一下IIS的系统架构以及Windows Server是如何响应HTTP请求的。
8.1.3 IIS的系统架构
IIS 6(运行于Windows 2003 Server)的架构如图 8?8所示。
图 8?8 IIS 6的架构
从图 8?8中可以看到,IIS 6架构由以下几个部分组成:
(1)HTTP.SYS:运行于Windows核心(Kernel)的一个组件,它负责侦听(Listen)来自于外部的HTTP请求(通常来自网络中另一台计算机上的浏览器),根据请求的URL将其转发给相应的应用程序池,由运行于应用程序池中的工作者进程来响应此HTTP请求。当此HTTP请求处理完成时,它又负责将处理结果发送出去(其接收者通常为发出HTTP请求的浏览器)。
为了提供更好的性能,HTTP.SYS内部建立了一个缓冲区,将最近的HTTP请求处理结果保存起来,如果发现某个HTTP请求“不久以前”处理过了(即在缓冲区中可以找到),它就简单地直接从缓冲区中取出这些结果发回给客户端(通常为发出HTTP请求的浏览器)。
(2)InetInfo:在IIS 5时代,InetInfo是IIS服务的主进程,在IIS 6中,它不再负责处理HTTP请求,但它继续负责管理除了WWW服务之外的其他互联网服务,比如用于文件传输的FTP服务和用于邮件收发的SMTP服务。
InetInfo内部维护了一个元数据库(Metabase),在这个数据库中存入了一些重要的信息,这些信息对于维护各种互联网服务(比如WWW和FTP)等是必不可少的。
(3)Worker Process:负责处理HTTP请求,被译为“工作者进程”,事实上,它是由一个可执行程序W3WP.EXE运行时所生成的一个进程[2],每一个工作者进程内部都可以管理一个或多个ASP.NET应用程序。工作者进程运行于一个应用程序池(Application Pool)中。IIS 6可以创建多个应用程序池,并指定某个ASP.NET应用程序在特定的应用程序池中运行(图 8?9)。
图 8?9 设定ASP.NET网站所属的应用程序池(图截自Windows 2003 Server)
一般情况下,一个应用程序池只有一个工作者进程,但也可通过配置必要的参数让多个工作者进程同时运行在同一个应用程序池中,在这种情况下,这个应用程序池被称为“Web Garden(Web园)”。
(4)WAS(Web Admin Service):这是一个监控程序,它一方面可以存取放在InetInfo元数据库(Metabase)中的各种信息,另一方面也负责监控应用程序池(Application Pool)中的工作者进程的工作状态况,必要时它会关闭一个老的工作者进程并创建一个新的取而代之。
[1] IIS 6中应用程序池的运行方式后文有详细介绍
[2]“进程(Process)”是一个具有一定独立功能的程序在一个数据集合上的一次动态执行过程。如用通俗的语言来表达,可以简单地将“进程”理解成一个正在运行的程序。
8.1.4 HTTP请求的处理过程
在了解了IIS的架构之后,来看一下IIS架构中的各个组成部分是如何相互配合处理HTTP请求的。
先来从总体上看看HTTP请求的处理过程(图 8?10)。
图 8?10 HTTP请求的处理过程
图 8?10清晰地展示出了HTTP请求处理就是浏览器与Web服务器间“一问一答”的过程。
首先,浏览器尝试连接Web服务器的80端口,如果Web服务器可以响应此连接请求,就在浏览器与Web服务器间建立了一个通讯链路,在此“通道”上浏览器与Web服务器可以相互发送与接收信息。
假设浏览器向Web服务器发出一个读取某ASP.NET站点上的某个ASPX网页的请求。当此请求通过网络到达Web服务器时,此请求被HTTP.SYS组件所接收。HTTP.SYS系统组件会检查此HTTP请求的相关信息,根据其URL将此HTTP请求发送给运行在某个应用程序池中的工作者进程处理。如果同时有多个针对此ASP.NET站点的HTTP请求,HTTP.SYS会将这些请求排队,加入到对应的应用程序池的HTTP请求队列中等待。
如果这是第一个对ASP.NET站点的HTTP请求,工作者进程会加载aspnet_isapi.dll,并将请求转给它,aspnet_isapi.dll接着会装载.NET CLR[1],创建一个针对此ASP.NET站点的应用程序域[2],然后启动一个复杂的由多个步骤和组件参与的处理流程,当此处理流程结束,要发回给客户端的结果(通常是HTML代码,当然也可以是其他类型的资源,比如由程序动态生成的图片)已经生成,此结果被转发给HTTP.SYS。
注意:对于以集成模式运行的IIS 7,.NET CLR在应用程序池一启动就自动装载,从而避免了临时装载CLR的花销。后继处理过程与IIS 6基本一致。
HTTP.SYS接收到请求的处理结果之后,将其缓存到缓冲区中,然后把处理结果发回给发出HTTP请求的浏览器。
上述过程是对IIS处理HTTP请求全过程的粗略描述。8.2节将选取这个处理过程中的主要阶段,详细介绍针对ASP.NET网页的HTTP请求处理过程。
8.1.5 ISAPI扩展、ISAPI筛选器和程序映射
在IIS的文档中经常会提到两个术语:ISAPI扩展和ISAPI筛选器。
1 ISAPI扩展
“ISAPI扩展(ISAPI Extension)”是一种可以添加到IIS中以增强Web服务器功能的程序,其载体为DLL文件。它通常直接负责响应HTTP请求。
根据HTTP请求要访问的资源扩展名(通过URL获取),IIS会选取特定的ISAPI扩展来处理这一请求,这一过程被称为“程序映射”。 而用于响应HTTP请求的这一ISAPI扩展被称为“HTTP Handler(HTTP处理程序)”。 图 8?11展示了IIS 6中的程序映射。
图 8?11 程序映射(IIS 6)
在图 8?11中可以看到,IIS指定对ASP.NET网页(其扩展名为.aspx)的请求将由aspnet_isapi.dll处理(图 8?12)。
图 8?12 aspnet_isapi.dll负责处理对ASP.NET网页的请求
IIS 7中的程序映射与IIS 6略有不同。当IIS 7以“经典模式”运行时,与IIS 6一样使用aspnet_isapi.dll响应针对“.aspx”的请求。但当IIS 7以“集成模式”运行时,则使用托管处理程序(System.Web.UI.PageHandlerFactory)响应针对“.aspx”的请求(图 8?13)。
图 8?13 IIS 7集成模式下的程序映射
2 ISAPI筛选器
“ISAPI筛选器(ISAPI Filter)”也是一种DLL,但它不负责生成HTTP请求,它的主要作用是响应某些特定的事件。当这些事件发生时ISAPI筛选器被调用,它可以修改传入或传出的HTTP数据。
在IIS 7中,使用“HTTP模块(HTTP Module)”取代了传统ISAPI筛选器的功能。
注意:ISAPI扩展与ISAPI筛选器名字很相近,但其在IIS中的地位和所起的作用是不同的。
[1] CLR(Comon Language Runtime):通用语言运行时,是.NET的核心,可以将其看成是一台虚拟的专用于运行.NET程序的计算机。
[2] 应用程序域(Application Domain):.NET引入的一种代码隔离机制,一个托管进程可以拥有多个应用程序域,在应用程序域中可以装载程序集,创建特定类型的对象,调用对象的方法。