IIS运行过程
有了上面的HTTP协议的知识回顾,下面来让我们看下IIS是怎样工作的?
IIS 5.X 已经距离我们很远了.好吧 XP默认的好像是的… 为万恶的IE6 默哀下0.0 .
这里我们来看一下IIS 6 的图示
根据上图简单分析下IIS6的运行过程
在 User Mode 下,http.sys 接收到 http request,然后它会根据 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。最后通过 AppManagerAppDomainFactory 的 Create 方法为 Application 创建一个 Application Domain;通过 ISAPIRuntime 的 ProcessRequest 处理 Request,进而将流程进入到 ASP.NET Http Runtime Pipeline。
PS几个知识点:
- HTTP.SYS:(Kernel)的一个组件,它负责侦听(Listen)来自于外部的HTTP请求,根据请求的URL将其转发给相应的应用程序池 (Application Pool)。当此HTTP请求处理完成时,它又负责将处理结果发送出去.为了提供更好的性能,HTTP.SYS内部建立了一个缓冲区,将最近的HTTP请求处理结果保存起来。
- Application Pool: IIS总会保持一个单独的工作进程:应用程序池。所有的处理都发生在这个进程里,包括ISAPI dll的执行。对于IIS6而言,应用程序池是一个重大的改进,因为它们允许以更小的粒度控制一个指定进程的执行。你可以为每一个虚拟目录或者整个Web 站点配置应用程序池,这可以使你很容易的把每一个应用程序隔离到各自的进程里,这样就可以把它与运行在同一台机器上其他程序完全隔离。从Web处理的角度看,如果一个进程死掉,至少它不会影响到其它的进程。
当应用程序池接收到HTTP请求后,交由在此应用程序池中运行的工作者进程Worker Process: w3wp.exe来处理此HTTP请求。 - Worker Process: 当工作者进程接收到请求后,首先根据后缀找到并加载对应的ISAPI扩展 (如:aspx 对应的映射是aspnet_isapi.dll),工作者进程加载完aspnet_isapi.dll后,由aspnet_isapi.dll负责加载 ASP.NET应用程序的运行环境即CLR (.NET Runtime)。
Worker Process运行在非托管环境,而.NET中的对象则运行在托管环境之上(CLR),它们之间的桥梁就是ISAPI扩展。 - WAS(Web Admin Service):这是一个监控程序,它一方面可以存取放在InetInfo元数据库(Metabase)中的各种信息,另一方面也负责监控应用程序池(Application Pool)中的工作者进程的工作状态况,必要时它会关闭一个老的工作者进程并创建一个新的取而代之。
再来看下网上对IIS7经典模式下的图解
IIS 7 应用程序池的托管管道模式“经典”模式也是这样的工作原理。这种模式是兼容 IIS 6 的方式, 以减少升级的成本。
小插曲
场景假定:
截获客户端的请求,并对请求进行重写。在IIS6中,请求的截获动作只能被限制在IIS加载aspnet_isapi.dll后,也就是说:如果该请求不是明确针对asp.net资源的请求(比如这个请求只是一个静态文件的请求,如www.cnblogs.com/index.html,这时我们就便不能在代码中编写截获请求的逻辑,因为IIS6是根据URL的后缀来映射并加载对应的isapi的,如果一个请求的url 是:www.cnblogs.com/index.aspx,根据".aspx"这个后缀,IIS6可以得知这个请求是针对asp.net资源的,应该加载aspnet_isapi.dll创建.net运行时并运行asp.net页面的代码,但很明显,诸如"www.cnblogs.com/index.html"这种请求,IIS6通常认为不是对asp.net资源的请求,因此不会加载 aspnet_isapi.dll来运行asp.net,我们即使在asp.net页面中编写了拦截请求的代码,也不会被执行。当然,这里我说通常是有原因的,因为我们可以在IIS6中添加通配符程序映射的方式,或者在web.config中对某种请求手动添加处理程序的方式,来迫使IIS6为非 asp.net资源类型的请求加载aspnet_isapi.dll。IIS6中对请求的执行流程如上.
咦,有木有人和我一样想到了URL Routing 和URL Rewriting ?
这里不做说明,大叔手记16传送门:http://www.cnblogs.com/TomXu/archive/2011/12/27/2303486.html
这个问题先放一下~~了解II7的集成模式也许可以有一些思绪
让我们再来看下IIS官网上对IIS7的图解
传送门 :http://www.iis.net/learn/get-started/introduction-to-iis/introduction-to-iis-architecture
1、当客户端浏览器开始 HTTP 请求一个WEB 服务器的资源时,HTTP.sys 拦截到这个请求。
2、HTTP.sys 联系 WAS 获取配置信息。
3、WAS 向配置存储中心(applicationHost.config)请求配置信息。
4、WWW 服务接收到配置信息,配置信息指类似应用程序池配置信息,站点配置信息等等。
5、WWW 服务使用配置信息去配置 HTTP.sys 处理策略。
6、WAS为请求创建一个进程(如果不存在的话)
7、工作者进程处理请求并对HTTP.sys做出响应.
8、客户端接受到处理结果信息。
IIS 7 应用程序池的托管管道模式(集成模式)华丽的变身
IIS7中对asp.net的请求不再是分两条处理管道,而是将asp.net和 IIS集成起来,这样做的好处是统一了请求验证工作,加强了asp.net对于请求的控制能力等等。在IIS7中,asp.net不再像IIS6一样只限定于aspnet_isapi.dll中,而是被解放出来,从IIS接收到HTTP请求开始,即进入asp.net的控制范围,asp.net可以存在于一个请求在IIS中各个处理阶段。甚至可以为部署在IIS7中的PHP应用提供基于asp.net的验证身份验证功能(传送门:http://msdn.microsoft.com/zh-cn/magazine/cc135973.aspx)。
好吧,戛然而止一下,篇幅有限:IIS部分告一段落 留一些遐想空间.
再来分析ASP.NET的运行机制