WebForms和WebServices作为.NET平台构建Web程序的两大利器,以其开发简单、易于部署的特点得到了广泛的应用,但殊不知微软公司在背后为我们做了大量的基础性工作,以至于我们开发人员只需简单地拖拖控件、写写一些页面级的代码就可以轻松地实现一些简单的应用程序。当然这种封装也不是没有好处的,至少从开发的角度而言它就可以极大地降低开发的难度,但是这种过度的封装使得我们开发人员当遇到有可能由底层引起的问题时就会束手无策,而且也会使得我们对知识的掌握和理解只停留在了表面而不得其内在本质。正是基于此,所以作者决定以一种探索的精神去试图解析和研究ASP.NET的内部运行机制,当然由于本人水平有限,也不可能对其各个方面理解很到位,姑且就当作本人的一家之言吧,有不对的地方还请各位同仁指正,这样大家可以共同学习提高。

一、IIS处理模型

  从用户发出一个请求(一般而言就是在浏览器地址栏中键入一个URL),到这个请求到达服务器后,最先作出响应的就是IIS(本部分只关注ASP.NET部分,至于TCP/IP不在讨论范围),所以我们就先从这开始讲起。由于IIS有不同的版本,而且其处理模型也大相径庭,所以我会单独分别加以说明和解释。

IIS 5 处理模型

深入理解ASP.NET的内部运行机制(转)

从上图我们可以清楚地知道,IIS在用户请求到达之后都做了哪些事情:

1.当用户请求到达后,工作在内核模式的TCP/IP驱动首先检测到请求,然后将其直接路由到inetinfo.exe进程;

  • inetinfo.exe通过监听WinSock端口(常见的TCP 80端口)接收请求,然后对其进行处理或者交由其扩展组件(ISPAI Extensions)进行处理;
  • IIS中的Metabase维护着一份脚本映射扩展表,即ISAPI Extension Mapping数据表,是用Binary写的。该数据表的作用就是当请求到达IIS的时候,IIS会分析该请求的资源文件的后缀名,然后再通过ISAPI Extension Mapping找到对应的ISAPI Extension;
  • 找到对应的ISAPI Extension后就可以把此请求交由其处理了,例如.aspx文件将由aspnet_isapi.dll来处理;
  • 如果找不到,即一个文件的扩展名没有被映射到ASP.NET,那么ASP.NET就不会去接收这个请求,当然更不会去处理此请求;
  • 我们可以自定义一个Handler去处理一个特殊的文件名扩展,当然前提是你必须得Map到ASP.NET并且必须在你应用程序的Web.config文件中注册这个自定义的Handler,更多信息,请参看文章//TODO
  • 3.用户请求由命名管道(为了提高性能,否则要在两个不同的进程间传递)从inetinfo.exe传给工作者进程aspnet_wp.exe;

    4.aspnet_wp.exe将用户请求交由HTTP运行时即.NET Runtime处理(接下来的处理流程将会在后面讨论)。

    IIS 6 处理模型

    深入理解ASP.NET的内部运行机制(转)

    从上图来分析IIS 6架构的处理流程:

  • HTTP.SYS:运行于Windows核心(Kernel)的一个组件,它负责侦听(Listen)来自于外部的HTTP请求(通常来自网络中另一台计算机上的浏览器),根据请求的URL将其转发给相应的应用程序池 (Application Pool)。当此HTTP请求处理完成时,它又负责将处理结果发送出去(其接收者通常为发出HTTP请求的浏览器)。为了提供更好的性能,HTTP.SYS内部建立了一个缓冲区,将最近的HTTP请求处理结果保存起来。
  • Application Pool:  相对于IIS5,IIS6改变了这个处理模型,IIS不再直接寄宿像ISAPI扩展的任何外部可执行代码。代替的是,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)。
    注意:工作者进程运行在非托管环境,而.NET中的对象则运行在托管环境之上(CLR),它们之间的桥梁就是ISAPI扩展。
  • WAS(Web Admin Service:这是一个监控程序,它一方面可以存取放在InetInfo元数据库(Metabase)中的各种信息,另一方面也负责监控应用程序池(Application Pool)中的工作者进程的工作状态况,必要时它会关闭一个老的工作者进程并创建一个新的取而代之。
  • 二、.NET运行时

    深入理解ASP.NET的内部运行机制(转)

      上面的图形简单描述了大概的处理流程,下面再用文字做些简单的说明:

    1.当请求到达.NET Runtime后,接下来的处理操作就将在托管环境中完成。首先.NET Runtime做两个动作,一是准备Hosting Environment,二是由ApplicationManager创建一个AppDomain并且把处理权交由AppDomain继续完成;

    2.在AppDomain中,由对象ISAPIRuntime启动操作,一方面经方法ProcessRequest()得到HttpWorkerRequest对象,另一方面由方法StartProcessing()生成HttpRuntime对象,接下来把处理权交给了HttpRuntime(HttpWorkerRequest对象将作为HttpRuntime方法中的参数被使用);

    3.HttpRuntime中,方法ProcessRequest将处理请求:

    [AspNetHostingPermission(SecurityAction.Demand, Level=AspNetHostingPermissionLevel.Medium)]
    public static void ProcessRequest(HttpWorkerRequest wr)
    {
        if (wr == null)
        {
            throw new ArgumentNullException("wr");
        }
        if (UseIntegratedPipeline)
        {
            throw new PlatformNotSupportedException(System.Web.SR.GetString("Method_Not_Supported_By_Iis_Integrated_Mode", new object[] { "HttpRuntime.ProcessRequest" }));
        }
        ProcessRequestNoDemand(wr);
    }

    相关文章: