WEB请求的全过程

本系列是以IIS6.0为准进行阐述的

 

    当我们在浏览器地址栏中键入比如http://192.168.1.1/test.aspx,回车后,相当于向服务器(192.168.1.1)发送了一个Web页(test.aspx)请求,这个请求经由HTTP.SYS后转发到IIS。那么在到达IIS之前,HTTP.SYS对这个请求做了什么?HTTP.SYS又是个啥呢?它又有什么特点呢?这就是本系列的第一站:HTTP.SYS

    HTTP.SYS是一个内核模式网络驱动程序。即HTTP.SYS运行在内核模式下,作为驱动程序而存在。从结构上来讲,HTTP.SYS是位于TCPIP.SYS之上的。也就是说,一个请求首先由TCPIP.SYS处理,然后才转发到HTTP.SYS上;同理,该请求被Web应用程序处理后作为响应返回时则是先到达HTTP.SYS在转发到TCPIP.SYS最后到达客户端浏览器。注意:TCPIP.SYS和HTTP.SYS都处于内核模式下。

如图:

 

注:为了避免用户应用程序访问或者修改关键的操作系统数据,windows提供了两种处理器访问模式:用户模式(User Mode)和内核模式(Kernel Mode)。一般地,用户程序运行在User mode下,而操作系统代码运行在Kernel Mode下。Kernel Mode的代码允许访问所有系统内存和所有CPU指令。

    

 

    接下来让我们看一下HTTP.SYS功能特点:

      (1) HTTP.SYS的主要功能是监听用户(来自于TCPIP.SYS)的HTTP请求。

      (2) 管理TCP连接

      (3) 验证HTTP请求。比如URL和Header长度等,如果验证没有通过则直接返回。否则将WEB请求放到适当请求队  列中,并对其进行排队。

      (4) 路由HTTP请求到正确的WEB应用程序池。HTTP.SYS中维护着一个从URL到WEB应用程序池的对应关系路由表(映射表),所以HTTP.SYS可以迅速将WEB请求转发到web应用程序。注意,如果WEB请求没找到相应的映射,则返回404错误,就是我们常见的那个并不雅观的页面。当然你也可以自己画一个漂亮的将这个页面覆盖掉。

      (5) 缓存web应用程序对于该请求的响应结果。当同一请求被频繁访问时可以不必转发到Web应用程序,直接从此缓存中将结果返回给用户,大大提高了其响应速度。

      (6)实现比如连接限制、连接超时、消息队列长度限制以及IIS宽带限制等控制。 

上面说了这么多,其最最重要的功能就是监听来自用户的WEB请求,请一定要记住。

 

    HTTP.SYS其模块结构,如图:

 

 

 

   

      上面介绍了HTTP.SYS是什么以及其功能特点,那么HTTP.SYS是如何工作的呢?

      当你创建一个WEB站点的时候,IIS就会在HTTP.SYS上注册这个站点,这样就会接收来自该站点的任何WEB请求。HTTP.SYS从功能上讲类似于一个转发器。发送收到的WEB请求到WEB应用程序,并且发送返回的响应到客户端。

       当IIS6.0在工作进程隔离模式下运行时,HTTP.SYS就监听用户请求,并为这些收到的WEB请求在适当的队列中进行排队。每个请求队列都对应一个应用程序池,一个应用程序池又对应一个HTTP.SYS中的请求队列和一个或多个工作进程。 

      通过上面的介绍我想也应该对一个WEB请求在HTTP.SYS中的历程有所了解了,即HTTP.SYS收到用户的请求后对其进行相关验证,通过则去映射表中查找其对应的应用程序池,找到后将该web请求转发到应用程序池的工作进程中,经WEB应用程序处理后最终又通过TCPIP.SYS将处理结果返回给用户浏览器。那么web请求被转发到Web应用程序池后,接下来会发生什么呢。

      上文说到一个WEB请求被HTTP.SYS转发到了WEB应用程序池。顾名思义,WEB应用程序池就是一个WEB应用程序的容器。那么这个WEB请求在WEB应用程序池中又有着怎样的经历呢,这不得不引出另外两个IIS6.0的核心组件:工作进程(WORKER PROGESS)和WEB管理器(WEB ADMIN SERVICE),这也就是本文重点所讲述的。

      在表述这两个组件之前,先来看一下它们的图示:

     

     

      我先来说说WWW Service,也就是WAS。WAS是一个管理和监视工作进程的组件,它宿主在SveHost.exe中,运行在用户模式下。WAS负责同MetaBase进行交互以获取其配置数据信息,这些配置信息会通过WAS注册到HTTP.SYS中。同时WAS还负责监视管理工作进程。一旦工作进程出现故障,WAS会为其创建新的工作进程以响应Web请求。

      当运行IIS的InetInfo.exe服务启动后,WAS服务(SvcHost.exe)也随之启动。此时WAS从InetInfo的MeteBase中读取配置信息并且初始化HTTP.SYS中的Namespace路由表(Namespace mapper),HTTP.SYS通过路由表中的数据条目来判定Web请求的URL所对应的应用程序池。此时,HTTP.SYS就会向WEB应用程序池发出启动工作进程的指令。当我们添加或删除一个应用程序池时,WAS会处理相应的变更信息,包括从HTTP.SYS中添加或删除该应用程序池的消息队列。WAS也会监听和处理来自应用程序池回收的配置变更信息。

      WAS还负责管理管理工作进程,包括启动工作进程和维护正在运行的工作进程。并判定何时启动工作进程,何时回收工作进程以及何时重新启动处于阻塞状态或不能处理更多WEB请求的工作进程。在工作进程隔离模式下,WAS负责健康管理和维护,包括应用程序池的健康监视,工作进程的回收以及对工作进程异常的迅速保护。     

      以上是对WAS的简述,接下来我着重说说工作进程(Worker Progress),在讲工作进程之前,我来大致说说WAS、WEB应用程序池、工作进程以及WEB应用程序它们之间的关系。如果把WEB应用程序池比作一个小区的话,那么工作进程(W3WP.exe)就相当于管理这个小区的物业,而web应用程序相当于这个小区的住户,WAS(SvcHost.exe)就相当于管理这个小区旁边的派出所。下面我把工作进程(W3WP.EXE)图放大,如下图:

     

      工作进程(W3WP.EXE)是一个用户模式下负责处理WEB请求的程序,比如处理返回静态页的请求,调用ISAPI扩展或ISAPI筛选器,运行CGI(Common Gateway Interface)。工作进程接收来自HTTP.SYS的WEB请求和向HTTP.SYS发送该请求的WEB响应。同时也会运行WEB应用程序代码,比如Asp.net Application和XML Web Service。工作进程主要通过程序集W3Core.DLL来实现所有WEB请求的处理逻辑。

       一个应用程序池中可包含多个工作进程,工作进程间是相互隔离的,直接和内核模式下的HTTP.SYS进行交互,互不影响。也就是说一个工作进程出现故障并不会影响其它的工作进程的正常运行。

      从上图我们看到工作进程包括如下两个程序):ISAPI扩展和ISAPI过滤器。ISAPI的全称是Internet Service Application Interface。通过ISAPI可以访问IIS提供的所有功能,比如通过它调用ASP.DLL对动态网页(aspx,ascx,asmx等)进行处理。而ISAPI过滤器可以修改和过滤来自客户端的WEB请求等,为什么要修改它的URL或HEADERS呢,这就涉及到CookieLess,即无Cookie验证,自己想想?!具体功能如下:

修改来自客户端的请求(URL或Headers),

控制物理文件到URL的映射

验证完成后修改或分析请求

修改客户端返回的响应

对“访问被拒绝”的响应运行自定义处理

当请求结束后执行相应的处理

同客户端的连接关闭后执行相应处理

记录日志和跟踪分析

执行自定义的身份验证

加密压缩等功能。

     可见一个WEB请求要想顺利到达WEB应用程序是多么地不容易。好了,说了这么多自己脑袋都懵了,还是捋一下WEB请求的思路吧。一个WEB请求经HTTP.SYS转发到WEB应用程序池对应的工作进程,如果该进程没启动则通过WAS来启动,没有找到相应的工作进程则创建,注意启动工作进程时会加载相应的Asp.net ISAPI动态库,然后加载CLR。这个请求通过ISAPI过滤器和ISAPI扩展的种种考验,最终就会来的WEB应用程序的面前。我还是用图例来描述一下这个WEB请求现在走到哪里了吧,此时还WEB请求的旅程并没有走完。

      

 

 上文我们主要描述了iis6.0的两个核心组件WAS和Worker Progress,而本文重点讲述一下WEB请求在工作进程中都经历了什么,下面我把描述工作进程的图示放大,如下:

   

 

    我们知道,当一个有效的WEB请求到达HTTP.SYS后,发现没有相应有效的工作进程,则HTTP.SYS会告诉WAS(svchost.exe),以为之创建并启动一个工作进程(w3wp.exe)。在启动工作进程的过程中加载ISAPI(非托管代码)以及CLR(托管代码),然后在工作进程中创建应用程序域。其实如上一系列操作只是为WEB请求准备好其运行环境。

当一个WEB请求进入已经准备好的工作进程边界(工作进程从HTTP.SYS的应用程序池对应的消息队列中取出该WEB请求),那此时首先会经过ISAPI FILTER的处理,比如修改http报头和URL等,具体功能参见上文。接下来就会将处理的WEB请求交给ISAPI EXTENSION。那么ISAPI EXTENSION会干什么呢?我们先看下图:

   

   

    我们从上图可以看出,它就是一个应用程序扩展名的映射,即文件扩展名与处理该文件的应用程序的一个映射表,接下来我们看看具有aspx扩展名的文件是由哪个应用程序集处理(dll)的,如下图:

   

    

    看到了吗?其实也就告诉我们对于aspx扩展名的文件,要交给aspnet_isapi.dll处理,其实大部分文件都映射到了aspnet_isapi.dll,也就是说大部分动态的web请求文件都交由程序集aspnet_isapi.dll来处理。对于静态文件比如jpg、js、以及css等都会直接将文件返回给客户端。注意:aspnet_isapi.dll是一个非托管的Win32动态库,里面封装了很多用于与web进行交互的函数,它的处理速度那是相当的快。另外它被加载到了工作进程中,也就是说非托管的aspnet_isapi.dll与托管的web应用都处于一个工作进程中,这显然会加快其处理速度。跨进程访问是要付出代价的,所以我们不必为此担心。那么如何才能调用aspnet_isapi.dll提供的一系列服务呢,这就引出了ISAPIRuntime,它的主要功能就是负责ISAPI扩展的非托管代码与托管代码之间的沟通与交互。您只要记住这点就行了,具体实现细节我认为没必要深究。如果您对此感兴趣可以借助reflector.exe等工具进行跟踪研判。

    我们的WEB请求走到到哪儿了,没错,它经过ISAPI顺利的进入到了ASP.NET通道接下来他会一直走啊走,经过HttpApplication、httphandles等经过处理后将其响应返回给http.sys,最终到达客户端浏览器。

 

    本来关于IIS6.0还有很多说不完的话题,比如asp.net application的生命周期,以及web page的生命周期、以及如何自定义httpmodules,如何自定义httphandles等等,网上这方面的资料已经很多了,我也不再赘述。

    其实写到此我只大概介绍了IIS6.0的三个核心组件HTTP.SYS、WAS以及Worker Progress,另外两个(Inetinfo.exe和IIS MetaBase)只是轻描淡写,如果有时间我会继续说说关于这两个核心组件的内容,另外会顺带说说SSL。

 

posted on 2010-09-02 00:57  啊T  阅读(3751)  评论(0编辑  收藏  举报