MVC之前的那点事儿系列,是笔者在2012年初阅读MVC3源码的时候整理的,主要讲述的是从HTTP请求道进入MVCHandler之前的内容,包括了原创,翻译,转载,整理等各类型文章,当然也参考了博客园多位大牛的文章,对此表示感谢,这次有时间贴出来,希望对大家有用。

主要内容

本文讲解的是:服务器接受Http Request请求之后,是如何进入.Net CLR,从而进一步操作的。

我们大家都知道,IIS必须先接受请求,然后才能有机会进入CLR,但对请求(request)是怎么从Web服务器传送到ASP.NET运行时的却不甚了解。IIS由于版本的不同,在进入CLR时候方式可能有所不同,本章节将就IIS5/6/7的三本版本的进入方式给予解释,通过对这些底层机制的了解,可以让我们对 ASP.net 有更深的理解。。

IIS 5 的 ASP.net 请求处理过程

IIS5核心特征是:IIS是允许在一个叫InetInfo.exe的进程上的,所以无论是aspx页面还是html页面都是通过这个进程处理的,其中,由于aspx页面扩展名映射到了aspnet ISAPI.DLL上,所以如果页面是aspx的话,aspnet ISAPI.DLL则创建aspnet_wp这个Worker Process,并在初始化的时候加载CLR,所以这是一个托管的环境。

需要注意的几点是:

  1. 同一台服务器只能运行一个 aspnet_wp 进程,也就是说所有的ASP.NET Web Application都在同一个Worker Process 中,但是不意味着他们共享同一个context和数据库, ASP.NET里有个AppDomain的概念,每个站点或虚拟目录都对应一个单独的AppDomain,每个AppDomain是隔离的,有自己独立的context上下文,所以安全没问题,所以我们的结论是:ASP.NET程序是继续AppDomain的,而不是基于Process的。
  2. ASP.NET  ISAPI 不但负责创建 aspnet_wp Worker Process,而且负责监控该进程,如果检测到 aspnet_wp 的 Performance 降低到某个设定的下限,ASP.NET  ISAPI 将结束掉该进程,在Request来了以后,ASP.NET ISAPI 将重新创建新的 aspnet_wp Worker Process。
  3. 由于 IIS 和 Application 运行在他们各自的进程中,他们之间的通信必须采用特定的通信机制。由于之间的通信是同机器不同进程的通信(local interprocess communications),处于Performance的考虑,他们之间采用基于Named pipe的通信机制。ASP.NET ISAPI和Worker Process之间的通信通过他们之间的一组Pipe实现。同样处于Performance的原因,ASP.NET ISAPI 通过异步的方式将Request 传到Worker Process 并获得 Response,但Worker Process 则是通过同步的方式向 ASP.NET ISAPI 获得一些基于 Server 的变量。

IIS 6 的 ASP.net 请求处理过程

IIS6和IIS5有3个非常不同的地方:接受请求(Http.sys),应用程序池(Application Pool),w3wp.exe Worker Process。

在IIS5里,InetInfo.exe附件监听并处理请求(Request),但在IIS6里,服务器是通过一个新组件Http.sys来接受请求(Request)。

Http.sys接收到http请求的时候,它会根据IIS中的 Metabase 查看该基于该 Request 的 Application 属于哪个Application Pool, 如果该Application Pool不存在,则创建之。否则直接将 request 发到对应Application Pool 的 Queue中。

每个 Application Pool 对应着一个Worker Process:w3wp.exe。在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。

注意:IIS5和IIS6还有一个区别是,在IIS5里ASP.NET ISAPI创建aspnet_wp Worker Process,进而加载CLR,但在IIS6里是w3wp通过Application Pool的map关系运行以后,才加载ASP.NET ISAPI,然后加载CLR。

IIS 7  的 ASP.net 请求处理过程

步骤 1 到 6 ,是处理应用启动,启动好后,以后就不需要再走这个步骤了,上图的8个步骤分别如下:

  1. HTTP.sys监听拦截客户端请求开始处理。
  2. HTTP.sys通过配置信息联系WAS获取相关信息。
  3. WAS 向配置存储中心请求配置信息。applicationHost.config。
  4. WWW 服务接受到配置信息,配置信息指类似应用程序池配置信息,站点配置信息等等。
  5. WWW 服务使用配置信息去配置 HTTP.sys 处理策略。
  6. WAS为这个请求对应的应用程序池(Application Pool)开启W3WP Worker Process。
  7. W3WP Worker Process处理以后,将Response返回给HTTP.sys。
  8. 客户端接受到Response内容。

W3WP.exe 进程中又是如果处理得呢?? 取决于IIS 7 的应用程序池托管管道模式是什么,IIS7目前有2个模式: 经典模式和集成模式。两种模式下的处理方式是不一样,看如下区别:

IIS7经典模式:

IIS7的经典模式和IIS6的处理方式是一样的,用户发送HTTP Request请求以后, IIS会先行处理,IIS会根据HTTP Request的类型进行筛选,如果是HTML 静态网页就由 IIS 自行处理,如果不是,就根据具体要求的内容类型,分派给各自的 IIS ISAPI extension;如果要求的内容类型是 ASP.NET,就分派给负责处理 ASP.NET 的 IIS ISAPI extension,也就是 aspnet_isapi.dll,然后再进入CLR。

IIS7集成模式:

IIS7集成模式是一个伟大的改进,已经预加载了CLR(不在依靠之前IIS版本的aspnet_ISPAI.DLL),也就是说所有的HTTP Request请求都要经过ASP.NET来处理(包括html, php等),也因为 ASP.NET 的诸多功能已经成为 IIS 7 的一部份,因此 ASP 程序、PHP 程序或静态 HTML 网页等类型的要求,也能使用像是Forms认证(Forms Authentication)或输出缓存(Output Cache)等 ASP.NET 2.0 的功能(但须修改 IIS 7 的设定值),也因为 IIS 7 允许自行以 ASP.NET API 开发并加入模块,因此 ASP.NET 网页开发人员将更容易扩充 IIS 7 和网站应用程序的功能,甚至能自行以 .NET 编写管理 IIS 7 的程序(例如以程控 IIS 7 以建置网站或虚拟目录)。

总结:

不同的IIS版本进入CLR的方式是不一样的,其中IIS版本之间最大的改变时:

  1. IIS5 到 IIS6 的改进,主要是 HTTP.sys 的改进。
  2. IIS6 到 IIS7 的改进,主要是 ISAPI 的改进。

提示:从下一章节开始,我们将进入微软.NET4和MVC3源码进行深入分析,所以该继续后面的章节之前,请先下载这些源代码,地址如下(只需要下载.NET4和MVC3,其它不需要):

http://referencesource.microsoft.com/

参考资料:

http://dotnetslackers.com/articles/iis/ASPNETInternalsIISAndTheProcessModel.aspx

http://dotnetslackers.com/articles/iis/ASPNETInternalsIISAndTheProcessModel2.aspx

http://www.cnblogs.com/riccc/archive/2007/07/08/asp-net-internals-iis-and-the-process-model.html

http://learn.iis.net/page.aspx/243/aspnet-integration-with-iis/

http://learn.iis.net/page.aspx/101/introduction-to-iis-architecture/

http://www.west-wind.com/presentations/howaspnetworks/howaspnetworks.asp

http://www.cnblogs.com/zhaoyang/archive/2011/11/16/2251200.html

http://www.dotnetfunda.com/articles/article821-beginners-guide-how-iis-process-aspnet-request.aspx

同步与推荐

本文已同步至目录索引:MVC之前的那点事儿系列

MVC之前的那点事儿系列文章,包括了原创,翻译,转载等各类型的文章,如果对你有用,请推荐支持一把,给大叔写作的动力。

MVC之前的那点事儿系列(1):进入CLR的更多相关文章

  1. MVC之前的那点事儿系列(10):MVC为什么不再需要注册通配符(*.*)了?

    文章内容 很多教程里都提到了,在部署MVC程序的时候要配置通配符映射(或者是*.mvc)到aspnet_ISPAI.dll上,在.NET4.0之前确实应该这么多,但是.NET4.0之后已经不要再费事了 ...

  2. MVC之前的那点事儿系列(8):UrlRouting的理解

    文章内容 根据对Http Runtime和Http Pipeline的分析,我们知道一个ASP.NET应用程序可以有多个HttpModuel,但是只能有一个HttpHandler,并且通过这个Http ...

  3. MVC之前的那点事儿系列(6):动态注册HttpModule

    文章内容 通过前面的章节,我们知道HttpApplication在初始化的时候会初始化所有配置文件里注册的HttpModules,那么有一个疑问,能否初始化之前动态加载HttpModule,而不是只从 ...

  4. MVC之前的那点事儿系列(9):MVC如何在Pipeline中接管请求的?

    文章内容 上个章节我们讲到了,可以在HttpModules初始化之前动态添加Route的方式来自定义自己的HttpHandler,最终接管请求的,那MVC是这么实现的么?本章节我们就来分析一下相关的M ...

  5. MVC之前的那点事儿系列(7):WebActivator的实现原理详解

    文章内容 上篇文章,我们分析如何动态注册HttpModule的实现,本篇我们来分析一下通过上篇代码原理实现的WebActivator类库,WebActivator提供了3种功能,允许我们分别在Http ...

  6. MVC之前的那点事儿系列(5):Http Pipeline详细分析(下)

    文章内容 接上面的章节,我们这篇要讲解的是Pipeline是执行的各种事件,我们知道,在自定义的HttpModule的Init方法里,我们可以添加自己的事件,比如如下代码: public class ...

  7. MVC之前的那点事儿系列(4):Http Pipeline详细分析(上)

    文章内容 继续上一章节的内容,通过HttpApplicationFactory的GetApplicationInstance静态方法获取实例,然后执行该实例的BeginProcessRequest方法 ...

  8. MVC之前的那点事儿系列(3):HttpRuntime详解分析(下)

    文章内容 话说,经过各种各样复杂的我们不知道的内部处理,非托管代码正式开始调用ISPAIRuntime的ProcessRequest方法了(ISPAIRuntime继承了IISPAIRuntime接口 ...

  9. MVC之前的那点事儿系列(2):HttpRuntime详解分析(上)

    文章内容 从上章文章都知道,asp.net是运行在HttpRuntime里的,但是从CLR如何进入HttpRuntime的,可能大家都不太清晰.本章节就是通过深入分析.Net4的源码来展示其中的重要步 ...

随机推荐

  1. 用curl向指定地址POST一个JSON格式的数据

    昨天的一个任务,用POST 方式向一个指定的URL推送数据.以前都用的数组来完成这个工作. 现在要求用json格式.感觉应该是一样的.开写. <?php $post_url = "ht ...

  2. Java-数组练习1

    1.已知2个一维数组:a[]={3,4,5,6,7},b[]={1,2,3,4,5,6,7}:把数组a与数组b 对应的元素乘积再赋值给数组b,如:b[2]=a[2]*b[2]:最后输出数组b的元素. ...

  3. Excel快速改变行列的次序

    改变行列次序是在Excel中常常需要进行的操作,多数用户的方法是先剪切要调整的行或列,然后选定目标位置,单击菜单“插入”→“剪切单元格”.   事实上,使用键盘来配合的话,改变行列的次序可以更快捷.比 ...

  4. Atitit  循环(loop), 递归(recursion), 遍历(traversal), 迭代(iterate).

    Atitit  循环(loop), 递归(recursion), 遍历(traversal), 迭代(iterate). 1.1. 循环算是最基础的概念, 凡是重复执行一段代码, 都可以称之为循环. ...

  5. 1.1.1. Atitit Cocos2d-JS v3.x的问题

    1.1.1. Atitit Cocos2d-JS v3.x的问题   1.1. Api 兼容性 场景切换的api都不兼容了...  删除了比较多的api...可以dep啊.. 1.2. gui布局,, ...

  6. SQLServer性能分析

    SQLServer性能分析 当数据库出现性能问题,应用出现运行缓慢的时候,下面这个东东能让你如获至宝 create table #sp_who2 ( SPID int ,status varchar( ...

  7. 复杂 XML 的 序列化 反序列化

    已知.xml(再此命名default.xml)文件,请将其反序列化到一个实例对象. <?xml version="1.0" encoding="utf-8" ...

  8. 数据访问模式:数据并发控制(Data Concurrency Control)

    1.数据并发控制(Data Concurrency Control)简介 数据并发控制(Data Concurrency Control)是用来处理在同一时刻对被持久化的业务对象进行多次修改的系统.当 ...

  9. (4) PIVOT 和 UPIVOT 的使用

    最近项目中用到了行转列,使用SQL SERVER 提供的PIVOT实现起来非常容易. 官方解释:详见这里 可以使用 PIVOT 和 UNPIVOT 关系运算符将表值表达式更改为另一个表. PIVOT ...

  10. 前端工程师技能之photoshop巧用系列第五篇——雪碧图

    × 目录 [1]定义 [2]应用场景 [3]合并[4]实现[5]维护 前面的话 前面已经介绍过,描述性图片最终要合并为雪碧图.本文是photoshop巧用系列第五篇——雪碧图 定义 css雪碧图(sp ...