Asp.net Process Model 之一:IIS 和ISAPI
学习了几篇进程模型,在此自己理顺一下思路,加深印象
进程模型主要是讲述从接到用户request到返回给用户response为止的一系列步骤,说明web server处理请求的流程。
一、IIS 5.X process model
该模式是windows 2000和XP系统的默认模式。借用一下博园里Artech的模型图说明一下:
我们把资源放入IIS的虚拟目录下,用户就可以通过web server请求这些资源。可部署的资源包括静态资源和动态资源,如:html、css、xml、asp.net application、WCF、Remoting、Web Services等。
如图所示,IIS和asp.net application运行在不同的进程中。IIS运行在InerInfo进程,此进程是本地系统进程,asp.net application运行在aspnet_wp的工作进程(worker process)中。InetInfo进程负责监听请求,并将请求送入到请求队列等待处理,处理请求后返回结果给客户端;aspnet_wp负责处理IIS转发的与asp.net相关的请求,并将结果返回给IIS。两进程通过Named Pipe进行通讯。
当用户通过browser向web server提交请求后,IIS根据请求资源的类型做出不同的处理操作。如果是静态资源请求,如纯html、css、js、图片文件等,IIS直接从目标地址中取出资源后,作为Http Response返回给客户端browser;如果是需要动态处理的资源,IIS则需要将request发送给相应的处理程序。处理程序负责响应此request,并把Http Response返回给IIS,再由IIS将Response返回给客户端browser。我们称这些处理程序为IIS ISAPI extension。ASP.NET资源的处理程序叫做ASP.NET ISAPI Extension —— aspnet_isapi.dll,它是一个native module,由IIS加载执行。IIS通过ISAPI extension mapping将资源类型与isapi extension处理程序关联。可通过IIS进行mapping设置,如下图:
IIS接受到asp.net资源请求后(如aspx页面),根据mapping设置获取到aspnet_isapi.dll,于是加载此dll。此后,request就转交给ISAPI处理。aspnet_isapi会创建一个aspnet_wp进程(如果此进程不存在),在初始化aspnet_wp的时候会加载CLR,从而为ASP.NET Application创建一个托管的运行环境,在CLR初始化时会加载两个重要的dll:AppManagerAppDomainFactory和ISAPIRuntime。通过AppManagerAppDomainFactory的Create方法为Application创建一个Application Domain;通过ISAPIRuntime的ProcessRequest处理Request,进而将流程拖入到ASP.NET Http Runtime Pipeline的范畴,ASP.NET Http Runtime Pipeline对Http Request接管Request,最终生成Html。
说明:
1 worker process工作在ASPNET账户下,该账户在安装.net framework时自动创建。所有的Application运行在同一个worker process中,也就是说,只有一个工作进程处于运行状态
2 在同一个process内,各Application通过App Domain技术进行隔离,彼此运行在相互独立、安全的环境下,一个Application对应一个AppDomain。即:一个worker process中同时包含一个或多个AppDomain
3 同一个AppDomain的request可以由多个线程服务,单线程不属于某个AppDomain,它可以服务于多个AppDomain,但是同一时间内,它属于一个appdomain
4 出于性能的考虑,ASP.Net ISAPI可以基于某些标准对worker process进程进行回收,这些标准放在mochine.config文件中,定义了诸如应用程序生命周期、等待或服务的队列长度、空闲时间等配置,一旦超过阈值,ASP.NET ISAPI extension将会创建新的Worker Process用于处理新的request,旧的worker process处理旧的request,但不接受新请求,处理完旧请求后销毁
二、IIS 6 based Process Model
该模式是windows 2003系统的默认模式。借用图:
以下摘自 http://www.cnblogs.com/artech/archive/2007/09/09/887528.html
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对应一个Worker Process:w3wp.exe。也就是说,和前一个版本的IIS不同的是,对于IIS 6来说,同一台机器上可以同时运行多个Worker Process,每个Worker Process中的每个Application domain对应一个Application。这样,Application之间不但能提供Application Domain级别的隔离,你也可以将不同的Application置于不同的Application Pool中,从而基于Process级别的隔离。对于Host 一些重要的Application来说,这样的方式可以提供很好的Reliability。创建Application Pool、为Aplication指定Pool过程如下图:
新建Application Pool:
选中一个Application,右键单击属性,为Application配置Application Pool:
在Performance方面,IIS 5.x是通过InetInfo.exe监听Request并把Request分发到Work Process。换句话说,在IIS 5.x中对Request的监听和分发是在User Mode中进行,在IIS 6中,这种工作被移植到kernel Mode中进行,所有的这一切都是通过一个新的组件:http.sys来负责。
在User Mode下,http.sys接收到一个基于aspx的http request,然后它会根据IIS中的Mapping查看该基于该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。
注:为了避免用户应用程序访问或者修改关键的操作系统数据,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。