Artech

Develop every application as an art using the most suitable technologies!

常用链接

统计

积分与排名

CnBlogs

专家的Blog|主页

最新评论

[原创]ASP.NET Process Model之一:IIS 和 ASP.NET ISAPI

前几天有一个朋友在MSN上问我“ASP.NET 从最初的接收到Http request到最终生成Response的整个流程到底是怎样的?”我觉得这个问题涉及到IISASP.NETASP.NET Runtime的处理模型的问题,并不是三言两语就能说清楚的,所以决定写这样一篇介绍IISASP.NET Runtime Process Model的文章,谈谈我对此的一个粗浅的认识,如果有什么不对的地方,希望大家及时指正。

这篇文章大体分为两个部分,第一部分我将谈谈IIS的两个不同的版本—IIS 5.x IIS 6(虽然IIS 7已经Release很长时间了,而且较之前两个版本发生了非常大的变化,由于本人缺乏对IIS 7深入的了解,所以在这里就不再介绍了,不过以后我将这方面的内容补上)的处理模型:IIS如何监听来自外界的Http request,如何根据ISAPI Extension Mapping将对于不同Resource的请求分发给不同的ISAPI Extension,基于ASP.NET ResourceASP.NET ISAPI如何将Request传递给ASP.NET Runtime 环境。第二部分将着重介绍在一个托管的ASP.NET Runtime 环境对传入的Http request的处理过程。我们先来看看IIS 5.xIIS 6的处理过程。

1.             一、IIS 5.x based Process Model

IIS 5.x一个显著的特征就是Web Server和真正的ASP.NET Application的分离。作为Web ServerIIS运行在一个名为InetInfo.exe的进程上,InetInfo.exe是一个Native Executive,并不是一个托管的程序,而我们真正的ASP.NET Application则是运行在一个叫做aspnet_wpWorker Process上面,在该进程初始化的时候会加载CLR,所以这是一个托管的环境。我们接下来将谈论aspnet_wp如何创建,aspnet_wpInetInfo.exe如何进行通信,以及简单介绍在aspnet_wp中,如何将Request 导入ASP.NET Rutime Pipeline

我们通过创建虚拟目录将资源HostIIS下,原则上,我们可以通过IIS访问置于虚拟目录下的所有Resource,这部仅仅包含一些静态资源文件,比如图片、纯Html文件、CSSJS等等,也包含一些需要动态执行的文件,比如aspxasmx等等,我们还可以将RemotingWCF Service HostIIS下。对于这些静态的文件,IIS直接提取对应的文件将其作为Http Response返回给Client,但是对于这些需要进一步处理的动态执行的文件,IIS必须将Request进一步传递给对应的处理程序,待处理程序执行完毕获得最终的Http Response通过IIS返回给Client。对于IIS来说,这些处理程序通过ISAPI Extension来体现。对于基于ASP.NETResource,其对应的ISAPI ExtensionASP.NET ISAPI,通过一个aspnet_isapi.dll承载。IISMetadata database维护着一个称为ISAPI Extension Mapping的数据表,负责将不同类型的Resource影射到对应的ISAPI Extension



上图像我们展示了
IIS 5.x如何处理一个基于ASP.NET Resource(以aspx为例)的Http Request的大体流程。首先用户通过Browser请求一个aspx pageBrower向对于得Web Server,也就是目标主机的IIS。在上面我们提到过,IIS运行在一个称为InetInfo.exe的进程中,InetInfo.exe是一个Native Executive,并非一个托管的程序。IIS分析Request的目标资源文件的扩展名(这里是aspx),通过ISAPI Extension Mapping获知对应的ISPAIASP.NET ISAPI,于是加载aspnet_isapi.dll。到此为止,该Request的处理交由ASP.NET ISAPI,处理。ASP.NET ISAPI会创建一个叫做aspnet_wp.exeWorker Process(如果该进程不存在的话),在aspnet_wp.exe初始化的时候会加载CLR,从而为ASP.NET Application创建一个托管的运行环境,在CLR初始化的使用会加载两个重要的dllAppManagerAppDomainFactoryISAPIRuntime。通过AppManagerAppDomainFactoryCreate方法为Application创建一个Application Domain;通过ISAPIRuntimeProcessRequest处理Request,进而将流程拖入到ASP.NET Http Runtime Pipeline的范畴,ASP.NET Http Runtime PipelineHttp Request的处理是一个相对复杂的过程,相关的介绍会放在本篇文章的下一部份。在这里我们可以把它看成是一个黑盒,它接管Request,最终生成Html

这基本上就是整个处理流程,很简单。不过在这里有几点需要特别指出的。

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

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

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

2.             二、IIS 6 based Process Model

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

1. 首先从Performance上看,IISapplication运行在不同的进程中,虽然他们之间采用了基于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 Processw3wp.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 ModeKernel Mode以及一些Windows底层的一些内容,推荐大家看看《Microsoft Windows InternalFour Edition Authored by Mark E.Russinovich & David A. Solomon



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

IIS Process Model部分就介绍到这里,在下部分中,我将介绍ASP.NET Http Runtime Pipeline

Reference:
The ASP.NET HTTP Runtime
ASP.NET Internals – IIS and the Process Model
ASP.NET Internals - The bridge between ISAPI and Application Domains
Microsoft® Windows® Internals, Fourth Edition: Microsoft Windows Server™ 2003, Windows XP, and Windows 2000


ASP.NET Process Model
[原创]ASP.NET Process Model之一:IIS 和 ASP.NET ISAPI
[原创]ASP.NET Process Model之二:ASP.NET Http Runtime Pipeline - Part I
[原创]ASP.NET Process Model之二:ASP.NET Http Runtime Pipeline - Part II

posted on 2007-09-09 16:43 Artech 阅读(5821) 评论(45)  编辑 收藏 所属分类: ASP.NET

评论

#1楼  2007-09-09 17:02 好文章 [未注册用户]

绝对好文,把IIS的处理流程讲得很清楚!   回复  引用    

#2楼  2007-09-09 17:03 不再潜水 [未注册用户]

LZ的每篇文章都很好,佩服啊!   回复  引用    

#3楼 [楼主] 2007-09-09 17:15 Artech      

@好文章
@不再潜水
谢谢两位的关注:)   回复  引用  查看    

#4楼  2007-09-09 18:58 Cat Chen      

为什么不把IIS7也包括上呢?IIS7相对于IIS6的变化,比起IIS6相对于IIS5的变化还要大得多哦。   回复  引用  查看    

#5楼  2007-09-09 19:10 随风流月      

@Cat Chen
IIS7 应该考虑 Server 2008,Vista 的那个没有意义,没有人会把它部署到生产环境.   回复  引用  查看    

#6楼 [楼主] 2007-09-09 19:21 Artech      

@Cat Chen
正是因为IIS 7.0具有太多革新,到目前为止还没有对它有一个深刻的认识,等我研究一下在把相关的内容加上。   回复  引用  查看    

#7楼 [楼主] 2007-09-09 19:24 Artech      

刚刚发现一个Bug,在第二张图片Kernel Mode里面的QueueA(AppPoolA)应该是QueueB(AppPoolB),在用PS画图的时候,用惯了Ctrl + C / Ctrl + V:)   回复  引用  查看    

#8楼  2007-09-09 20:36 戏水      

今天刚好也在看《asp.net2.0高级编程》里的相关部分。
Artech 兄的文章 真是不错。
深入浅出 诲人不倦   回复  引用  查看    

#9楼 [楼主] 2007-09-09 20:53 Artech      

@戏水
但愿不是毁人,呵呵!!
作为ASP.NET专家的Dino Esposito的这本书写得确实不错,可以和该书的姊妹篇《ASP.NET2.0技术内幕》一起看,相信效果更好!   回复  引用  查看    

#10楼  2007-09-09 21:57 yjdwchun [未注册用户]

老哥,你计算机方面懂得有点多哟!
呵呵
出了社会工作了学的东西就是了多些哈,加油。。。。。。。。。。   回复  引用    

#11楼  2007-09-09 22:10 txd_lf [未注册用户]

Application Pool Queue和Worker Process(w3wp.exe)之间用什么方式来通信呢???   回复  引用    

#12楼  2007-09-09 23:22 一瓢      

to:Artech
有没有Dino Esposito的ASP.NET 2.0 - Programming Microsoft ASP.NET 2.0 Applications - Advanced Topics.pdf
完整的电子版本,如果有,请发给我一份,谢谢
wg74000@hotmail.com   回复  引用  查看    

#13楼 [楼主] 2007-09-10 00:09 Artech      

@一瓢
很抱歉,我只有书,没有电子版。   回复  引用  查看    

#14楼 [楼主] 2007-09-10 00:10 Artech      

@txd_lf
很佩服你的钻研精神啊,对于这个的具体实现,我还真的不是太清楚,让我去查查资料,又结果我再这里公布.   回复  引用  查看    

#15楼 [楼主] 2007-09-10 01:42 Artech      

@yjdwchun
3x:)   回复  引用  查看    

#16楼  2007-09-10 06:19 deerchao      

What's the difference (when using) between static fields/singleton and session/applicaton/cache?   回复  引用  查看    

#17楼  2007-09-10 09:00 txdlf [未注册用户]

asp.net isapi 在5.0是运行在IIS(InetInfo.exe)主程序里面,然后IIS通过它 与aspnet_wp.exe通讯,而在6.0是运行在w3wp.exe里面。那么在6.0里面asp.net isapi的作用和在5.0里面相比好像不是很明显了,或者说有什么不同的地方   回复  引用    

#18楼  2007-09-10 12:04 Clark Zheng      

不错,赞一个先!   回复  引用  查看    

#19楼 [楼主] 2007-09-10 15:19 Artech      

@deerchao
Static Filed是定义在Global.asax中,具有全局意义的变量,和Application变量差不多,但是由于它是强类型的,所以对于Static变量的访问从Performance上讲会由于Application变量。

Application变量是一个置于HttpApplicationState对象的一个Entry,HttpApplicationState对一个Dictionary对象。Application变量和一个HttpApplication对象邦定在一起,因而具有全局意义,被每个Session共享和修改,而前必须考虑Thread Safety。

Session变量作为HttpSessionState对象的一个Item,故名思义,他是和Session绑定在一起,每个Session的Session变量互补影响,因而也无需考虑Thread Safety。

Cache是出于Peformance和系统的Robust(比如DB Connection断开,可以访问Cache,而不致使Appliation崩溃)而设计,和Application对象一样具有全局意义,不过ASP.NET为Cache提供Thread Safety的支持,我们在编程的时候无需考虑多线程安全的问题。Cache最引人注目的是其expiration policy,我们可以定义给基于时间和Dependence的expiration policy。我们设置可以定义一个Callback用于其失效时调用。   回复  引用  查看    

#20楼 [楼主] 2007-09-10 15:24 Artech      

@txdlf
ASP.ISAPI在不同的IIS里面的起的作用还是满大的,在IIS 5.x中,对应的Dll是被IIS的InetInfo.exe进程加载,并负责创建和监管Worker process:aspnet_wp.exe。

在IIS 6 中则是被Worker Process:w3wp.exe加载,负责Load CLR,创建AppDomain,并将Request forward给ASP.NET Http Runtime Pipeline。   回复  引用  查看    

#21楼 [楼主] 2007-09-10 15:24 Artech      

@Clark Zheng
thanks!!   回复  引用  查看    

#22楼  2007-09-10 18:19 deerchao      

@Artech
谢谢!

我记得在哪里看到过在某些情况下(好像是检测到了变化,需要重启AppDomain时),同一个虚拟目录可能会暂时同时对应两个AppDomain(一个继续处理未完成的Request,另一个处理新的), 那么这时两个AppDomain里的static和Application,Cache之间的关系如何呢?它们会不会跨越AppDomain的隔离?有没有处理这一问题的最佳实践或指导原则什么的?   回复  引用  查看    

#23楼  2007-09-10 18:21 deerchao      

@Artech

发现你一个小错误哦: Session里的数据仍然需要考虑多线程间的同步.因为一个用户可能同时打开多个页面.   回复  引用  查看    

#24楼 [楼主] 2007-09-10 18:57 Artech      

@deerchao
我的理解是这样的:
HttpApplicationState对象创建的时机是:Client第一次访问Application对应Virtual Direcotry的任何Resource。在我的映像中,ASP.NET好像没有提供这样的机制将Application State从一个崩溃的Application下恢复起来。

我觉得Application,Static Field和Cache的一个共性是他们都是全局的,而且他们都不支持Web Farm和Web Garden。Application,Static Field和Cache的最大不同就是,前者的生命周期会为此到Application终止,所以使用一定要考虑到内存的使用效率,而Cache在使用的时候就灵活得多,可以根据具体数据的稳定状况实施不同的过期策略。

还有一个问题不得不考虑得是:他们的数据都不支持多处理器的Web Server和多个Web Server的场景(Web Farm和Web Garden),在这种情况下最好不要使用Application和Static Field,因为不能实现其全局性,所以一般选择将数据直接存储在永久的介质中,比如DB。   回复  引用  查看    

#25楼 [楼主] 2007-09-10 19:20 Artech      

@deerchao
实际上ASP.NET为我们做了加锁机制   回复  引用  查看    

#26楼  2007-09-11 19:59 过河小卒      

透彻明了   回复  引用  查看    

#27楼 [楼主] 2007-09-11 20:05 Artech      

@过河小卒
^_^   回复  引用  查看    

#28楼  2007-09-13 09:33 巫云      

好厉害啊,原来这样啊,难怪那次没regiis时,显示的错误是MetaData数据库没有访问权限。   回复  引用  查看    

#29楼  2007-09-13 11:24 晓木      

知其然知其所以然,赞一个..   回复  引用  查看    

#30楼 [楼主] 2007-09-13 17:37 Artech      

@晓木
感谢你的关注,3x^_^   回复  引用  查看    

#31楼  2007-09-15 19:28 蛙蛙池塘      

关注一下,理解IIS的架构,对开发高性能高可用性的socketserver有很大的帮助
  回复  引用