SAL

  博客园  :: 首页  :: 新随笔  :: 订阅 订阅  :: 管理

【转】IIS 内部运行机制及Asp.Net执行过程详解

Posted on 2012-08-13 15:47  SAL  阅读(3542)  评论(0编辑  收藏  举报

一直以来对一个Asp.net页面穿过IIS后就返回给浏览器一个HTML页面感觉很是神奇。虽然做技术这么长时间了,也曾经大致了解过一点来龙去脉,但是如果你真的问起我比较详细的过程,我还真的回答不上来,好吧,今天我们就来详细了解一下这个神奇的过程。

IIS(Internet Information Service)历史

 

1、IIS 1.0 

IIS 1.0最初是随着Windows NT 3.51的Service Pack3一同发布的,IIS 1.0作为一个服务集,提供了HTTP、Gopher以及WAIS等功能。尽管IIS提供了这些功能,但是与其他很多第三方公司的服务器相比要逊色很多, 而且IIS并没有与Windows操作系统紧密结合起来,而是在Windows操作系统出现之后独立研发的。

 

2、IIS 2.0 

Windows NT 4.0出现以后,IIS发布了2.0版本,IIS 2.0最与众不同之处在于,它能够与Windows NT操作系统紧密结合,可以利用Windows的安全账号功能,可以通过一个管理控制台提供集成的管理功能。IIS 2.0引入了HTTP主机头和一个Web浏览器接口。 

以上1.0与2.0的时代程序开发方式是CGI(Common Gateway Interface)和 ISAPI(Internet Server Application Programming Interface),微软开启简便开发语言ASP现在还未诞生。 

 

3、IIS 3.0 

IIS 3.0以内嵌Windows NT 4.0 Service Pack3的方式一同发布(1996年12月),并且引入了ASP和应用服务器的概念。ASP诞生了,作为ASP.NET的先驱,它是一个在服务器端创建动态Web页面的脚本编程环境。 

 

4、IIS 4.0 

1997年9月,IIS 4.0被包含于Windows NT 4.0 Option Pack中,IIS 4.0引入了ASP 2.0(已经也不再提供 Gopher 協定的功能),这是一个基于对象的ASP版本,ASP 2.0提供了5个内置对象,为ASP页面提供了标准化的功能。IIS 4.0是最后一个可以独立下载的IIS,也是最后一版可以在操作系统之外安装的IIS。 

 

5、IIS 5.0和IIS 5.1 

2000年11月,IIS 5.0随同Windows Server 2000发布,从IIS 5.0开始,如果操作系统不升级,则IIS版本也不会升级。IIS 5.1随同Windows XP Professional发布,就所有基本功能而言,IIS 5.0和IIS 5.1完全相同,仅仅因为其所依附的操作系统不同而存在微小差异(內建了限十個同时连接,并且只允许建立一个网站)。从IIS 5.0开始,IIS 已经成为操作系统的一项服务。基于文件扩展名,IIS 5.0一颗满足处理静态内容、ISAPI函数以及ASP脚本的要求。通过将ASP脚本自动传递给ASP引擎,可以绕过静态内容处理部分,从而提高了页面处理速度,这个特性现在依然保留在最新的IIS 7.5中。 同时ASP也迈入3.0时代。

 

6、IIS 6.0 

2003年4月,IIS 6.0随同Windows Server 2003发布,IIS 6.0是一个里程碑式的版本,带来了重大更新。 

1)默认的安全性 

2)处理请求 

3)HTTP压缩

4)内核模式和永久性缓存 

5)XML Metabase 

6)应用程序池 

7)FTP服务 

8)SMTP和POP3服务 

 

7、IIS 7.0

 

如果说IIS 6.0是一个里程碑式的版本,那么IIS 7.0就要用脱胎换骨来形容了。IIS 7.0随同Windows Vista和Windows Server 2008发布,IIS 7.0是在IIS 6.0基础上重新开发的,将ASP.NET与请求管道进行了集成是IIS 7.0所作出的最为重大的改变。此外,IIS 7.0的可扩展性也得到了提高,提供了配置委托,使用XML配置文件,加入了请求跟踪与诊断功能。IIS 7.0的模块化设计也有利于开发人员定制模块,将第三方资源与IIS 7.0更好的结合。新添加的PowerShell和AppCmd命令行工具使得自动化开发与管理IIS 7.0变得更加容易。正是从IIS 7.0开始,告别了用系统光盘安装IIS的历史。

 

1)集成的请求管道 

2)高度可配置性 

3)组件化 

4)安全性 

5)IIS Manager

6)诊断 

7)兼容性 

8)FTP 7.0 

9)SMTP(NO POP3) 

 

8、IIS 7.5 

IIS 7.5随同Windows 7与Windows Server 2008 R2发布,从版本号就可以看出IIS 7.5不是一次重大的版本升级,而是对IIS 7.0进行了扩充与完善,但是也带来了很多的新特性:

  1. 支持配置系统的自定义追踪。
  2. 通过配置轮询来审核或追踪配置变更的能力——这是来自托管商们的要求,特别是想要监视客户们更改配置系统。
  3. ASP.NET支持不同的CLR版本(例如,CLR4.0),随着多个CLR版本的使用,这个特性对开发者切换版本很重要。我们也将此功能向后移植到Windows Server 2008 SP2。
  4. Application pools的更好控制,可以为每应用程序池指定CLR设置,可以用新的Application Pool性能计数器监视性能。
  5. 可委派自定义错误,这是来自开发者的最多要求,他们想让非管理员在本地或远程改变自定义错误。
  6. IP restriction list的IPv6支持。
  7. Request filtering的更细粒度控制,特别对query strings来帮助防止SQL注入式攻击。Request filtering现在也支持请求特定的规则,使SQL注入规则仅对特定请求适用。
  8. Nego2支持,将允许内置支持LiveID providers,FedSSP,和更小粒的Kerberos/NTLM使能。
  9. 支持不要求密码的Managed Service Accounts域账号。
  10. AppPool identity支持——这个太复杂了,以后单独帖子会另行讲。
  11. 支持application pool预热,大型应用程序会需要"起动"一个应用程序池,这样最初的请求们会有更好的性能。

 

9、IIS 8 

IIS8将随 WindowServer8beta版本发布。IIS8新功能旨在将大规模Web服务器聚集起来。但是众多功能中一个很好的效果在于怎样分拨更小的服务器甚至单独的服务器。 

下面就是IIS8给我们带来的新特性: 

CPU节流 

SSL的可扩展性 

SSL可管理性 - 中央证书存储(CCS) 

动态IP限制 

FTP登录限制 

Application模块初始化方式的改进 

配置文件大小的控制 

网络套接字的优化 

详情请参阅:http://weblogs.asp.net/owscott/archive/2012/03/01/what-s-new-in-iis-8.aspx

 

IIS内部运行机制

 

OK,我们还是从IIS 5.x开始说起吧,因为IIS 5.x算是微软IIS产品的分界线,IIS5与II6及以上版本的运行机制有很大的不同。作为IIS6及以上版本的前辈,IIS 5.x对之后IIS的发展有很重要启示。

 

1、IIS 5.x内部运行机制

IIS 5.x已经可以以配置的方式来进行运行,当然这个不小的进步是针对于之前的IIS来说的。

当一个HTTP请求从客户端发送过来之后会被WEB服务器进行Queue并进行分解归类,如果某个请求仅包含静态文件的请求,比如CSS,JS,Html文件或者虚拟目录所包含的文件如图片,IIS直接提取对应的文件将其作为Http Response返回给Client,如果事情仅仅是这样,我们很多人就会失业了,呵呵。但是对于这些需要进一步处理的动态执行的文件,IIS必须将Request进一步传递给对应的处理程序,待处理程序执行完毕获得最终的Http Response通过IIS返回给Client。如果一个请求中包含动静态请求,那么静态内容会等到动态内容生成HTML后组合在一起返回给Client。对于IIS来说,这些处理程序通过ISAPI Extension来体现。ISAPI Extension接收到请求页的扩展名之后会到IIS的Metadata database维护着一个称为ISAPI Extension Mapping的数据表查询,负责将不同类型的Resource影射到对应的ISAPI Extension。对应.ASPX的Mapping是ASP.NET ISAPI,至此,ASP.NET ISAPI会创建一aspnet_wp.exe的worker process(若该Process不存在的话)。当地一个ASP.NET接收到Application中的任何一个.ASPX请求时,名为ApplicationManager的类会创建一个ApplicationDomain(应用程序域)。ApplicationDomain会为全局变量提供应用程序隔离,并允许单独写真每个应用程序。在应用程序域中,将为名为 HostingEnvironment 的类创建一个实例,该实例提供对有关应用程序的信息(如存储该应用程序的文件夹的名称)的访问。如果需要,ASP.NET 还可对应用程序中的顶级项进行编译,其中包括 App_Code 文件夹中的应用程序代码。创建了应用程序域并对 HostingEnvironment 对象进行了实例化之后,ASP.NET 将创建并初始化核心对象,如 HttpContext、HttpRequest 和 HttpResponse。 HttpContext 类包含特定于当前应用程序请求的对象,如 HttpRequest 和 HttpResponse 对象。 HttpRequest 对象包含有关当前请求的信息,包括 Cookie 和浏览器信息。 HttpResponse 对象包含发送到客户端的响应,包括所有呈现的输出和 Cookie。

初始化所有核心应用程序对象之后,将通过创建 HttpApplication 类的实例启动应用程序。 如果应用程序具有 Global.asax 文件,则 ASP.NET 会创建 Global.asax 类(从 HttpApplication 类派生)的一个实例,并使用该派生类表示应用程序。创建 HttpApplication 的实例时,将同时创建所有已配置的模块。 例如,如果将应用程序这样配置,ASP.NET 就会创建一个 SessionStateModule 模块。 创建了所有已配置的模块之后,将调用HttpApplication 类的 Init 方法。 

在处理该请求时将由 HttpApplication 类执行以下事件。 希望扩展 HttpApplication 类的开发人员尤其需要注意这些事件。

  1. 对请求进行验证,将检查浏览器发送的信息,并确定其是否包含潜在恶意标记。
  2. 如果已在 Web.config 文件的 UrlMappingsSection 节中配置了任何 URL,则执行 URL 映射。
  3. 引发 BeginRequest 事件。
  4. 引发 AuthenticateRequest 事件。
  5. 引发 PostAuthenticateRequest 事件。
  6. 引发 AuthorizeRequest 事件。
  7. 引发 PostAuthorizeRequest 事件。
  8. 引发 ResolveRequestCache 事件。
  9. 引发 PostResolveRequestCache 事件。
  10. 根据所请求资源的文件扩展名(在应用程序的配置文件中映射),选择实现 IHttpHandler 的类,对请求进行处理。 如果该请求针对从 Page 类派生的对象(页),并且需要对该页进行编译,则 ASP.NET 会在创建该页的实例之前对其进行编译。
  11. 引发 PostMapRequestHandler 事件。
  12. 引发 AcquireRequestState 事件。
  13. 引发 PostAcquireRequestState 事件。
  14. 引发 PreRequestHandlerExecute 事件。
  15. 为该请求调用合适的 IHttpHandler 类的 ProcessRequest 方法(或异步版 IHttpAsyncHandler.BeginProcessRequest)。 例如,如果该请求针对某页,则当前的页实例将处理该请求。
  16. 引发 PostRequestHandlerExecute 事件。
  17. 引发 ReleaseRequestState 事件。
  18. 引发 PostReleaseRequestState 事件。
  19. 如果定义了 Filter 属性,则执行响应筛选。
  20. 引发 UpdateRequestCache 事件。
  21. 引发 PostUpdateRequestCache 事件。
  22. 引发 EndRequest 事件。
  23. 引发 PreSendRequestHeaders 事件。
  24. 24.引发 PreSendRequestContent 事件。

 

IIS 5 模式的特点: 

1、首先,同一台主机上在同一时间只能运行一个 aspnet_wp 进程,每个基于虚拟目录的 ASP.NET Application 对应一个 Application Domain ,也就是说每个 Application 都运行在同一个 Worker Process 中,Application之间的隔离是基于 Application Domain 的,而不是基于Process的。 

2、其次,ASP.NET  ISAPI 不但负责创建 aspnet_wp Worker Process,而且负责监控该进程,如果检测到 aspnet_wp 的 Performance 降低到某个设定的下限,ASP.NET  ISAPI 会负责结束掉该进程。当 aspnet_wp 结束掉之后,后续的 Request 会导致ASP.NET ISAPI 重新创建新的 aspnet_wp Worker Process。 

3、最后,由于 IIS 和 Application 运行在他们各自的进程中,他们之间的通信必须采用特定的通信机制。本质上 IIS 所在的 InetInfo 进程和 Worker Process 之间的通信是同一台机器不同进程的通信(local interprocess communications),处于Performance的考虑,他们之间采用基于Named pipe的通信机制。ASP.NET ISAPI和Worker Process之间的通信通过他们之间的一组Pipe实现。同样处于Performance的原因,ASP.NET ISAPI 通过异步的方式将Request 传到Worker Process 并获得 Response,但是 Worker Process 则是通过同步的方式向 ASP.NET ISAPI 获得一些基于 Server 的变量。

 

2、IIS6 的 ASP.net 请求处理过程

Reliability 和Performance永远不我们从事软件开发不变的主题。作为Host 基于Http Application的IIS来说,这两方面就显得尤为重要了。我们从IIS 5.x到IIS 6 的演变,不难看出IIS 6在前一个版本基础上所作的改进也是基于这两个方面。在介绍IIS 6的处理模型之前,我们先看看IIS 5.x都什么样缺陷: 

1. 首先从Performance上看,IIS和application运行在不同的进程中,虽然他们之间采用了基于Named Pipe的异步通信方式,但是一个基于进程之间的通信对性能的影响确实不能从根本上解决。

2. 其次,从Reliability来考虑,一台机器上只能运行一个worker process,每个Application运行在同一个进程中,虽然基于Application Domain的隔离能提供一定的Reliability,但是一旦真个进程崩溃,所有的Application都受影响。所以我们有时候需要提供一个基于Process的隔离性。 

基于Reliability的改进,IIS 6引入了Application Pool。顾名思义,Application Pool就是一个application的容器,在IIS 6中,我们可以创建若干Application Pool,在创建Web Application的时候,我们为它指定一个既定的application pool。在运行的时候,一个Application Pool对应一个Worker Process:w3wp.exe。也就是说,和前一个版本的IIS不同的是,对于IIS 6来说,同一台机器上可以同时运行多个Worker Process,每个Worker Process中的每个Application domain对应一个Application。这样,Application之间不但能提供Application Domain级别的隔离,你也可以将不同的Application置于不同的Application Pool中,从而基于Process级别的隔离。对于Host 一些重要的Application来说,这样的方式可以提供很好的Reliability。 

在Performance方面,IIS 5.x是通过InetInfo.exe监听Request并把Request分发到Work Process。换句话说,在IIS 5.x中对Request的监听和分发是在User Mode中进行,在IIS 6中,这种工作被移植到kernel Mode中进行,所有的这一切都是通过一个新的组件:http.sys来负责。 

注:为了避免用户应用程序访问或者修改关键的操作系统数据,windows提供了两种处理器访问模式:用户模式(User Mode)和内核模式(Kernel Mode)。一般地,用户程序运行在User mode下,而操作系统代码运行在Kernel Mode下。Kernel Mode的代码允许访问所有系统内存和所有CPU指令。关于User Mode和Kernel Mode以及一些Windows底层的一些内容,推荐大家看看《Microsoft Windows Internal》Four Edition, Authored by Mark E.Russinovich & David A. Solomon。

在Kernel Mode下,http.sys接收到一个基于Aspx的HttpRequest,然后它会根据IIS中的Metabase查看该基于该Request的Application属于哪个Application Pool,如果该Application Pool不存在,则创建之。否则直接将request发到对应Application Pool的Queue中。我上面已经说了,每个Application Pool对应着一个Worker Process:w3wp.exe,毫无疑问他是运行在User Mode下的。在IIS Metabase中维护着Application Pool和worker process的Mapping。WAS(Web Administrative service)根据这样一个mapping,将存在于某个Application Pool Queue的request 传递到对应的worker process(如果没有,就创建这样一个进程)。在worker process初始化的时候,加载ASP.NET ISAPI,ASP.NET ISAPI进而加载CLR。最后的流程就和IIS 5.x一样了:通过AppManagerAppDomainFactory的Create方法为Application创建一个Application Domain;通过ISAPIRuntime的ProcessRequest处理Request,进而将流程进入到ASP.NET Http Runtime Pipeline。

 

3、IIS7 的 ASP.net 请求处理过程

被模块化的IIS7可以按照功能安装,执行服务器的模块。重新架构的IIS7更能弹性的执行与填充。首当其冲的优点就是降低服务器资源的消耗,并且提升了WEB服务器的效率,其次,可以避免不必要的攻击,甚至你可以自定义服务器。

IIS7提供的模块

 

IIS7 站点启动并处理请求的步骤如下图:

步骤 1 到 6 ,是处理应用启动,启动好后,以后就不需要再走这个步骤了。

上图的8个步骤分别如下:

1、当客户端浏览器开始HTTP 请求一个WEB 服务器的资源时,HTTP.sys 拦截到这个请求。

2、HTTP.sys 经WWW服务器发送请求发送到WAS.

3、WAS 向配置存储中心请求配置信息。applicationHost.config。

4、WWW 服务接受到配置信息,配置信息指类似应用程序池配置信息,站点配置信息等等。

5、WWW 服务使用配置信息去配置 HTTP.sys 处理策略。

6、根据请求WAS为Application Pool启动一个进程.

7、进程处理请求并返回结果给HTTP.sys.

8、客户端接受到处理结果信息。

W3WP.exe 进程中又是如果处理得呢? IIS 7 的应用程序池的托管管道模式分两种:经典和集成。 这两种模式下处理策略各不相通.

 

IIS 6 以及 IIS7 经典模式的托管管道的架构

在IIS7之前,ASP.NET 是以 IIS ISAPI extension 的方式外加到 IIS,其实包括 ASP 以及 PHP,也都以相同的方式配置(PHP 在 IIS 采用了两种配置方式,除了 IIS ISAPI extension 的方式,也包括了 CGI 的方式,系统管理者能选择 PHP 程序的执行方式),因此客户端对 IIS 的 HTTP 请求会先经由 IIS 处理,然后 IIS 根据要求的内容类型,如果是 HTML 静态网页就由 IIS 自行处理,如果不是,就根据要求的内容类型,分派给各自的 IIS ISAPI extension;如果要求的内容类型是 ASP.NET,就分派给负责处理 ASP.NET 的 IIS ISAPI extension,也就是 aspnet_isapi.dll。下图是这个架构的示意图。 

IIS  7 应用程序池的托管管道模式  经典  模式也是这样的工作原理。 这种模式是兼容IIS 6 的方式, 以减少升级的成本。

 

IIS  7 应用程序池的 托管管道模式  集成模式

而 IIS 7 完全整合 .NET 之后,架构的处理顺序有了很大的不同(如下图),最主要的原因就是 ASP.NET 从 IIS 插件(ISAPI extension)的角色,进入了 IIS 核心,而且也能以 ASP.NET 模块负责处理 IIS 7 的诸多类型要求。这些 ASP.NET 模块不只能处理 ASP.NET 网页程序,也能处理其他如 ASP 程序、PHP 程序或静态 HTML 网页,也因为 ASP.NET 的诸多功能已经成为 IIS 7 的一部份,因此 ASP 程序、PHP 程序或静态 HTML 网页等类型的要求,也能使用像是Forms认证(Forms Authentication)或输出缓存(Output Cache)等 ASP.NET 2.0 的功能(但须修改 IIS 7 的设定值)。也因为 IIS 7 允许自行以 ASP.NET API 开发并加入模块,因此 ASP.NET 网页开发人员将更容易扩充 IIS 7 和网站应用程序的功能,甚至能自行以 .NET 编写管理 IIS 7 的程序(例如以程控 IIS 7 以建置网站或虚拟目录)。

 

4、IIS8 的 ASP.net 请求处理过程 

从IIS8的新特性可以看出,IIS8对于ASP.NET的执行过程并没有做太大的变化,所以整个执行过程应该和IIS7是一样的,只是在局部做了性能的优化。

 

Reference:

ASP.NET Internals – IIS and the Process Model

http://dotnetslackers.com/articles/iis/ASPNETInternalsIISAndTheProcessModel.aspx

Introduction to IIS Architecture

http://learn.iis.net/page.aspx/101/introduction-to-iis-architecture/

模組化的 IIS 7 與 .NET 能力整合

http://www.microsoft.com/taiwan/technet/columns/profwin/33-iis7-componentization-integration.mspx

IIS 5.0 和 6.0 的 ASP.NET 应用程序生命周期概述

http://msdn.microsoft.com/zh-cn/library/ms178473.aspx

ASP.NET Process Model之一:IIS 和 ASP.NET ISAPI

http://www.cnblogs.com/artech/archive/2007/09/09/887528.html

What’s New in IIS 8

http://weblogs.asp.net/owscott/archive/2012/03/01/what-s-new-in-iis-8.aspx