尽管IIS 7.0的架构与IIS 6.0差异甚大,甚至IIS 7.0代码库都是完全重新编写的,但是IIS家族系列中的许多概念和大多数架构仍然延续下来。尽管可以编写管道模块来代替多数ISAPI应用程序,但是ISAPI仍然存在。工作进程和应用程序池也依然存在,进程隔离也以类似的方式继续发挥作用,inetinfo.exe和Http.sys仍然执行类似的功能。然而,在IIS 7.0中,Web服务器已经成为应用服务器,并且已经成为各个版本(包括core server版本)的Windows Server 2008操作系统中的有机组成部分。
IIS 6.0是许多应用程序(如ASP、ASP.NET和SharePoint)的支持平台,与此不同的是,IIS 7.0则成为应用程序本身的组成部分。在许多方面,IIS 7.0就是应用程序框架,可以支持应用程序代码和应用程序功能。IIS 7.0的架构就是围绕着这个基本概念进行设计的,因此,开发人员获得了极大的自由,开发人员不仅可以对其开发的应用程序进行替换、调优和改良,现在还可以对Web服务器进行替换、调优和改良。IIS 7.0的模块化和可扩展性远远超过了ISAPI扩展,在IIS 6.0中,ISAPI扩展主要用于处理某种类型的文件。利用IIS 7.0,开发人员可以修改服务器功能来满足其开发的应用程序的需要。
一、集成管道模式
IIS改善和发展的主要因素是IIS已经成为应用程序(特别是ASP.NET)的支持平台。通过将ASP.NET直接集成到IIS 7.0中,IIS 7.0进一步推动了平台的发展。从管理功能到身份验证,乃至请求处理管道本身,相关功能都已经集成到IIS 7.0之中。将管道集成到IIS 7.0中具有两个好处:一是为基于ASP.NET的Web应用程序及IIS 7.0扩展提供了更好的性能,二是通过使用托管代码获得了更好的控制能力。
ASP.NET的性能之所以能够得到改善,是因为ASP.NET应用程序不再需要退出管道并加载ISAPI进程来处理ASP.NET代码,然后再返回到管道为客户提供响应信息。为了保持应用程序的兼容性,IIS 7.0仍然支持经典管道模式,但是,现在应该尽可能地使用新的集成管道。
1. 经典模式
在IIS 6.0中,ASP.NET扮演了一个ISAPI过滤器的角色,也就是说,请求退出管道后,由aspnet.dll进行处理,然后返回到管道进行进一步处理,最终将响应返回给客户端。如图2-4所示,在IIS 6.0中,一个客户端的HTTP请求将沿着管道移动,直到确定了一个处理程序,如果这个文件是一个ASP.NET文件,那么它就转入ASP.NET ISAPI过滤器,通过ISAPI的处理,在将一个HTTP响应返回给客户端之前,这个请求还将返回管道。IIS 7.0继续提供了这种模式,称为经典模式。
2. 集成管道模式
利用IIS 7.0中的集成管道,开发人员可以将自己的托管代码在管道中集成为一个模块。在先前版本的IIS中,这需要开发ISAPI过滤器或应用程序,对多数开发人员而言,这是一项难度很高的工作。在IIS 7.0中,可以用托管代码开发模块,并且模块可以作为请求管道的组成部分。如图2-5所示,利用IIS 7.0的集成管道模式,可以在管道中处理ASP.NET文件,这样可以在处理过程的任意一个步骤使用ASP.NET代码。因为ASP.NET已经集成到管道中,所以,诸如身份验证之类的ASP.NET功能也可以用于处理非ASP.NET内容。每个请求都可以由IIS和ASP.NET进行处理,而不必考虑其所属类型。
与ASP.NET集成也意味着可以使用ASP.NET身份验证对任何文件、文件夹,以及IIS 7.0的功能,从而有效地进行访问控制。在IIS 7.0出现之前,因为ASP.NET需要退出管道才能完成处理工作,所以任何不是由ASP.NET处理的文件,如HTML、Perl,甚至图形图像等内容,都无法由ASP.NET进行处理,因此也不会由ASP.NET身份验证机制来进行访问控制。所以,就必须使用Windows集成的身份验证或自定义的身份验证机制对不是由ASP.NET处理的文件进行访问控制。利用集成管道,可以大大简化身份验证方法的开发工作。
3. 将应用程序迁移到集成管道
为了与先前版本的IIS保持兼容,IIS 7.0仍然提供了经典管道模式。如果某个应用程序在集成管道模式下运行存在着兼容性问题,那么便可以在经典管道模型下运行这个应用程序。因为在集成管道模式下,web.config配置文件结构与经典管道模式有所区别,所以,如果使用了httpModules或httpHandlers,那么必须将其迁移到新的模式中。对于大多数ASP.NET应用程序而言,将其迁移到新的管道模式的过程比较直接,可以使用IIS 7.0命令完成迁移操作。
在默认情况下,IIS 7.0需要在集成管道中配置ASP.NET应用程序,多数应用程序都可以正常工作,如果应用程序无法正常工作,也会生成配置错误信息,报告具体发生了什么情况。通过使用AppCmd.exe,IIS 7.0提供了一个命令行方法。AppCmd.exe可以将应用程序配置迁移到集成管道,这样就可以消除大部分由不兼容配置文件导致的错误。可以在命令行输入以下命令:
appcmd.exe migrate config {Application Path}
我们需要将上述命令中的{Application Path}替换为网站名称和应用程序名称,其形式为default web site/application1。
4. 应用程序池和管道
管道模式是针对应用程序池的,可以在这个应用程序池中运行应用程序。为了将一个应用程序配置为在经典管道模式下运行,必须为经典管道创建一个应用程序池,并且将这个应用程序指派给这个应用程序池。也可以为经典管道配置一个应用程序池,并且为这个应用程序池指派一些应用程序,并将这些应用程序迁移到这个应用程序池中。最后令这个应用程序池运行在集成管道模式下。
二、可扩展性和模块化
IIS 7.0的模块式架构与先前版本的IIS中inetinfo.exe的单体架构不同。IIS 7.0中包括40多个组件,此外,还可以将定制开发的模块或由第三方开发的模块添加到IIS 7.0中。关于如何开发自定义模块,可以参考MSDN提供的图像版权模块(参见MSDN页面http://msdn2.microsoft.com/en-us/library/bb332050.aspx)。通过开发自定义模块,可以扩展核心服务器的功能。
利用模块化,IIS 7.0完成了两项任务。第一项任务是只需要加载应用程序执行或配置过程中需要的模块,这样就减少了IIS受到攻击的可能性,同时还减少了加载到内存中的代码数量。服务器管理的指导原则是:如果不需要做某事,那么就不要把对应的程序代码加载到内存中。IIS 7.0很好地实现了这个指导原则。模块化完成的第二项任务是提供了将定制的模块插入到管道中的能力。利用这个扩展功能,在Windows Server 2008发行之后,开发人员可以将集成模块添加到IIS中,这个模块与微软公司开发的模块看起来完全一样。
模块
IIS 7.0提供了40多个模块,可以处理从身份验证令牌缓存、ISAPI过滤器,乃至URL映射的功能。同时,是否安装这些功能,完全取决于Web网站和应用程序的需要。一般情况下,多数模块都被安装在系统中,例如HTTP缓存和HTTP日志功能等,利用这些模块提供的功能,我们可以将HTTP请求和标准的IIS日志在内核模式下缓存。其他功能,例如Digest身份验证或CGI模块,分别可以用于进行Digest身份验证和GCI应用程序,所以,除非必须支持这些功能,否则一般都无须安装这些模块。
下面我们对随Windows Server 2008一同发行的模块进行了归纳。
公用例程模块--公用例程模块是用于处理内部服务器操作的,但是不直接处理请求。这些模块提供了缓存功能,缓存对象包括文件、身份验证令牌,以及服务器状态--总而言之,缓存那些与URI请求有关的内容。如果不安装公用例程模块,那么系统性能将因为缓存减少而降级。
托管引擎:ASP.NET--这是一个独立的特殊模块,即ManagedEngine模块,这个模块的功能是将ASP.NET集成到请求管道中。如果不使用这个模块,那么IIS请求管道基本上就只能够运行于经典模式。
IIS 7.0本机模块--本机模块是指那些不依赖于ASP.NET框架编写的代码。这些模块主要是那些在IIS 6.0中编写,并且移动到IIS 7.0模块中的功能,这些代码仍然处于本机模式,这样有利于向后兼容。这些模块不需要使用ASP.NET框架,因此可以运行于core server版本Windows Server 2008服务器的IIS 7.0中,core server版本的Windows Server 2008没有提供ASP.NET框架。
托管模块--托管模块运行在托管代码中,这些代码是使用ASP.NET开发的。这些模块必须依赖于ASP.NET,例如Forms身份验证等功能,还包括需要处理配置文件、角色,以及ASP.NET会话状态等模块。
三、IIS Manager的可扩展性
在IIS 7.0中,IIS Manager是一个基于Windows表单的应用程序,与其他基于Windows表单的应用程序一样,具有良好的可扩展性。扩展管理用户界面时,首先需要使用一个模块提供程序,模块提供程序是一个服务器方的基础ASP.NET类,包括了IIS Manager模块的配置信息。在administration.config文件中存在一节名为moduleProviders的内容,这节内容定义了IIS Manager可以使用的模块,本章下面描述了这节内容。在同一个文件的modules一节内容中,列出了在Web服务器中实现的所有模块。
与此对应的客户端模块(注意,这个"客户"是IIS Manager中的客户程序,它有可能在服务器上运行)是基于Windows表单的应用程序,这些应用程序可以管理模块提供程序中的模块。为了支持对这个表单进行编程,微软公司提供了Microsoft.Web.Management.Client名称空间和Microsoft.Web.Management.Client.Win32名称空间,利用这两个名称空间,开发人员可以完成继承开发,从而保证了一致性和兼容性。
四、Metabase
IIS 7.0不再使用metabase,但是又并非完全不再使用metabase,这是因为IIS 7.0为了保持与IIS 6.0的兼容性,metabase仍然在IIS 7.0中存在。但是IIS 7.0从metabase中删除了与配置有关的内容,这部分内容的格式是专有的,因此内容本身难以理解。删除的内容被转移到XML配置文件中,这样,与配置有关的内容就成为用标准ASCII文本格式保存的工业界标准格式的文件了。IIS 7.0将几乎所有与配置有关的内容都保存在这些普通文本格式的XML文件中,这些内容可以用文本编辑器进行编辑,还可以用IIS Manager进行管理。之所以说"几乎",是因为某些IIS配置信息仍然保存在注册表中。因为IIS仅在自身启动之后才可以读取配置文件,所以某些在IIS启动时必须使用的配置项只能保存在注册表中。
某些遗留系统仍然需要使用metabase。与IIS 6.0相同的是,FTP、SMTP和NNTP等的配置信息仍然保存在metabase中,这是因为在IIS 7.0中,这些功能与IIS 6.0是完全相同的,没有做出任何改变。注意:如果服务器是从Windows Server 2003和IIS 6.0升级而来的,并且在升级前已经安装了NNTP,那么这个结论对NNTP才是成立的。IIS 7.0不再支持NNTP,Windows Server 2008也不再提供NNTP。
FTP则有所不同。与Windows Server 2008一同发行的FTP服务程序,连同SMTP服务程序,与Windows Server 2003提供的FTP服务程序和SMTP服务程序是完全相同的。SMTP并无任何变化,但是IIS 7.0还另外提供了一个FTP服务程序,这个FTP服务程序可以从www.iis.net下载。
1. applicationHost.config和web.config
applicationHost.config和web.config是两个掌控IIS 7.0配置的文件。web.config可以在网站级和应用程序级对配置进行控制,而applicationHost.config可以控制服务器本身。因为配置是可继承的,所以web.config可以重新定义更高级别的设置。通过使用配置锁定和管理委托,管理员可以使开发人员和更低级别的管理者控制特定的配置部分,同时将其他配置部分锁定以防止修改。
文件applicationHost.config保存在%windir%/system32/inetsrv/config目录下,遵循形如<attribute-name>="<default-value>" [<metadata>] [<description>]的标准格式。这个文件中的配置节内容与以下代码类似:
<system.webserver>
<defaultDocument enabled="true">
<files>
<add value="Default.aspx" />
</files>
</defaultDocument>
</system.webserver>
它为服务器启用了默认访问文档,将该文档设置为Default.aspx,并且设置为仅可访问Default.aspx。通过修改web.config文件中网站级的设置,可以对这个设置进行修改,其语法与上述内容是完全相同的,请参考下面的代码。下面的代码只是将包括了web.config文件的网站的默认访问文档从Default.aspx修改为Home.asx。其他网站仍然要从applicationHost.config文件中继承相关设置。
<system.webserver>
<defaultDocument enabled="true">
<files>
<remove value="Default.aspx" />
<add value="Home.aspx" />
</files>
</defaultDocument>
</system.webserver>
在默认安装的情况下,IIS 7.0并没有在网站的根目录下创建web.config文件,因此,所有的设置都保存在applicationHost.config文件中。通过使用IIS Manager修改诸如默认文档等网站设置,可以在网站根目录下创建一个web.config文件,这个文件中保存了网站配置信息。同时,即使在没有ASP.NET的情况下,这个文件还保存了ASP.NET应用程序配置信息。此外,web.config文件中还保存了所有与applicationHost.config文件中默认内容不同的IIS设置。
为什么applicationHost.config没有被命名为webServer.config?
先前版本的IIS使用metabase保存IIS的配置信息。在IIS 7.0开发团队将配置信息迁移到IIS 7.0配置文件的过程中,为什么没有将配置文件直接命名为webServer.config呢?IIS 7.0已经为其他应用程序平台使用IIS 7.0的某些功能提供了支持,例如,其他应用程序平台可以在applicationHost.config文件中保存配置信息,并且可以使用Windows Process Activation Service。Windows Communication Foundation(WCF)就是这类平台之一。
2. 其他XML配置文件
IIS 7.0和Web网站配置还受到其他XML配置文件的影响,可以在%windir%/system32/ inetsrv/config目录下找到这些文件,此外,文件administration.config也会对IIS 7.0和Web网站配置产生影响,因为这个文件中保存了IIS Manager的配置。最后,redirection.config也会产生影响,因为这个文件中保存了集中配置文件的信息。
redirection.config文件只是简单地保存了指导Web服务器访问正确的集中配置文件的信息,以及访问这些文件的身份证书。这个文件的内容一般为以下形式内容:
<configuration>
<configSections>
<section name="configurationRedirection" />
</configSections>
<configurationRedirection enabled="true" path="//server1/centralconfig$/" userName="domain1.local/config" password="Passw0rd1" />
</configuration>
administration.config文件保存了多得多的信息,例如,IIS Manager可以使用哪个模块等。利用如下内容的配置项,可以将默认文档模块添加到IIS Manager中,并且可以对所有网站生效。
<location path=".">
<modules>
<add name="defaultDocument" />
</modules>
</location>
需要添加自定义模块,那么administration.config文件就非常重要,因为必须首先在administration.config文件中为这些自定义模块添加生成一个项,然后才能在GUI管理界面中使用这些自定义模块。
3. Metabase Compatibility
遗留管理接口为IIS 7.0用XML配置文件进行系统管理提出了一个问题,如果IIS 7.0没有提供这些遗留接口,那么IIS 7.0中的某些修改可能会导致与IIS 6.0兼容的应用程序和例程产生一些问题。metabase compatibility为解决兼容性问题提供了支持。在IIS 7.0的默认安装过程中,metabase compatibility并未安装到系统中,因为一般情况下都不会用到这项功能,我们可以在安装IIS 6.0 manager时安装metabase compatibility。
需要使用metabase compatibility的脚本和应用程序是无法在IIS Manager中进行委托的,因此也不能访问IIS 7.0管理功能。因此,在IIS 7.0中移植这些应用程序与执行委托迁移过程颇为相似,在Windows Server 2008发行后,这些应用程序可能在很短时间内就可以修改完毕并对外发行。
metabase compatibility在处理遗留功能时,以及为遗留功能提供ADSI和WMI接口时,工作于API级别上。metabase compatibility对管理功能的调用进行了重新映射,使之能够调用合适的IIS 7.0函数,并且通过使用applicationHost.config文件中的配置项对这些映射进行了持久化。
五、WAS和工作进程
IIS 7.0提供了IIS 6.0的所有类似组件,例如侦听进程、工作进程和应用程序管理器,但是,IIS 7.0把这些内容从w3svc迁移到了Windows Process Activation Service(WAS)。在IIS 6.0和Windows Server 2003中,Http.sys截获的所有请求都被发送到一个HTTP侦听进程,这个HTTP侦听进程将请求传递给w3svc中某个合适的工作进程,在工作进程中,应用程序管理器把请求转发给具体的应用程序进行处理。虽然在IIS 7.0中存在类似的过程,但是WAS不仅处理HTTP请求,还可以处理TCP、命名管道和MSMQ。HTTP请求是由Http.sys截获的,并且在传递给WAS之前,就已经传递给w3svc中的HTTP管理器,但是,其他请求都是通过WAS侦听器的适配器接口转发给配置管理器和进程管理器的,而没有经过w3svc。
Http.sys和SMSsvchost.exe(SMSsvchost.exe是非HTTP侦听器的宿主)都位于IIS 7.0之外。这说明这些侦听器所截获的请求都可以在IIS 7.0之外进行处理,而Windows通信基础服务(Windows communication foundation service)可以作为服务运行,也可以作为Windows应用程序运行,还可以作为IIS 7.0之外的其他进程来运行。对于喜欢冒险的程序员来说,WAS是可以扩展的,当然,这需要编写自定义的侦听器处理程序,并且需要编写与此对应的应用程序域的协议处理程序。