ASP.NET与IIS是紧密联系的,由于IIS6.0与IIS7.0的工作方式的不同,导致ASP.NET的工作原理也发生了相应的变化。

IIS6(IIS7的经典模式)与IIS7的集成模式的不同

IIS6的运行过程:

分析上图可知:

在 User Mode 下,http.sys 接收到 http request,然后它会根据 IIS 中的 Metabase 查看基于该 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。最后通过 AppManagerAppDomainFactory 的 Create 方法为 Application 创建一个 Application Domain;通过 ISAPIRuntime 的  ProcessRequest 处理 Request,进而将流程进入到 ASP.NET Http Runtime Pipeline。

几个知识点:

  • HTTP.SYS:(Kernel)的一个组件,它负责侦听(Listen)来自于外部的HTTP请求,根据请求的URL将其转发给相应的应用程序池 (Application Pool)。当此HTTP请求处理完成时,它又负责将处理结果发送出去.为了提供更好的性能,HTTP.SYS内部建立了一个缓冲区,将最近的HTTP请求处理结果保存起来。
  • Application Pool:  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)。
    Worker Process运行在非托管环境,而.NET中的对象则运行在托管环境之上(CLR),它们之间的桥梁就是ISAPI扩展。
  • WAS(Web Admin Service):这是一个监控程序,它一方面可以存取放在InetInfo元数据库(Metabase)中的各种信息,另一方面也负责监控应用程序池(Application Pool)中的工作者进程的工作状态况,必要时它会关闭一个老的工作者进程并创建一个新的取而代之。

IIS7的运行过程:

分析上图可知:

1、当客户端浏览器开始 HTTP 请求一个WEB 服务器的资源时,HTTP.sys 拦截到这个请求。

2、HTTP.sys 联系 WAS 获取配置信息。

3、WAS 向配置存储中心(applicationHost.config)请求配置信息。

4、WWW 服务接收到配置信息,配置信息指类似应用程序池配置信息,站点配置信息等等。

5、WWW 服务使用配置信息去配置 HTTP.sys 处理策略。

6、WAS为请求创建一个进程(如果不存在的话)。

7、工作者进程处理请求并对HTTP.sys做出响应。

8、客户端接受到处理结果信息。

除了IIS的整体运行方式不同之外,IIS7相比IIS6最大的不同之处在于它提供了两种应用程序池管道模式:

经典模式:是与IIS 6或者之前版本保持兼容的一种模式,一个典型问题就是,在处理ASP.NET这种动态网站的时候,它是通过一个所谓的ISAPI程序,作为插件的方式来工作的。针对不同的动态应用程序(例如ASP,PHP等),会需要不同的ISAPI(Internet Server Application Programe Interface,互联网服务器应用程序接口)。如图,在IIS中,打开“处理程序映射”,可以看到aspx类型页面的处理程序为aspnet_isapi.dll。

下图展示了IIS7经典模式与IIS6的应用程序池管道模式运行原理,针对不同的请求,会指定不同的ISAPI(dll)进行处理:

集成模式:asp.net不再像IIS6一样只限定于aspnet_isapi.dll中,而是被解放出来,从IIS接收到HTTP请求开始,即进入asp.net的控制范围,asp.net可以存在于一个请求在IIS中各个处理阶段。允许我们将ASP.NET更好地与IIS集成,甚至允许我们在ASP.NET中编写一些功能(例如Module)来改变IIS的行为(扩 展)。集成的好处是,不再通过ISAPI的方式,提高了速度和稳定性。至于扩展,则可以使得我们对于IIS,以及其他类型的请求有更多的控制。(例如,我 们希望静态网页也具备一些特殊的行为)。如图

如下图在IIS7集成模式中,打开处理程序映射,可以看到aspx类型页面所对应的不再是一个dll,而是一个类型。

总结与扩展:

对于处理ASP.NET应用程序而言,IIS6及IIS7的经典模式需要aspnet_isapi.dll来处理,而IIS7集成模式不需要aspnet_isapi.dll来处理,而可以直接根据文件扩展名找到相应的处理程序接口。例如aspx的处理程序是System.Web.UI.PageHandlerFactory类型。

介绍完IIS的工作原理,来看一下ASP.NET内部的运行机制。

首先看一下IIS处理模型:

上面介绍IIS工作原理时,已经介绍了从发起HTTP请求,到响应请求的过程,这里主要介绍当请求到达.NET Runtime之后,.NET运行时所发生的一系列工作。

先看如下的.NET运行时工作序列图:

1.HTTP请求进入Web服务器后,首先由HTTP.SYS来判断请求的页面是否存在,如果存在的话将把请求信息转交给.NET Runtime。在这部分实际是完成两个步骤,在将请求转交给.NET Runtime的同时将请求信息封存在HTTPWorkRequest类中供其它步骤调用。HttpWorkRequest类在以后的操作中至关重要,它第一次将Http请求信息转换为类信息。
2.当请求到达.NET Runtime后,接下来的操作将会在托管环境中完成,这时请求就真正进入了.NET中,对请求信息的操作是由.NET的底层类库来实现。首先.NET Runtime将会针对请求信息做两个动作,一是准备HostingEnvironment;二是调用ApplicationManager类为HTTP请求动态的分配AppDomain,并把处理权交给AppDomain。
3.HTTP请求进入AppDomain后,将由对象ISAPIRuntime来接管,一方面经方法ProcessRequest()得到HttpWorkerRequest对象,另一方面由方法StartProcessing()生成HttpRuntime对象,接下来把处理权交给了HttpRuntime(HttpWorkerRequest对象将作为HttpRuntime方法中的参数被使用)。
4.HTTPRuntime接收到Http请求后,方法ProcessRequest处理请求。将对第1步中的HTTPWorkRequest类中的信息进行操作,具体的实现由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);
}
internal static void ProcessRequestNoDemand(HttpWorkerRequest wr)
{
RequestQueue queue = _theRuntime._requestQueue;
if (queue != null)
{
wr = queue.GetRequestToExecute(wr);
}
if (wr != null)
{
CalculateWaitTimeAndUpdatePerfCounter(wr);
wr.ResetStartTime();
ProcessRequestNow(wr);
}
}
internal static void ProcessRequestNow(HttpWorkerRequest wr)
{
_theRuntime.ProcessRequestInternal(wr);
}

5.在HttpRunTime中经过一系列的驱动后,将会在ProcessRequestInternal方法中为Http请求分配应用程序。在这一步中还将创建HttpContext对象。

context = new HttpContext(wr, false); // 基于HttpWorkerRequest生成HttpContext
IHttpHandler applicationInstance = HttpApplicationFactory.GetApplicationInstance(context); // 得到HttpApplication
handler2.BeginProcessRequest(context, this._handlerCompletionCallback, context); // 由HttpApplication处理请求

6.经过步骤5后HTTP请求信息才由基本信息转交给了Asp.net中的各个对象。接下来的操作会触发一些列的管道事件,这时的请求才真正转到HttpModule和HttpHandler中。
接下来我们看看常说的管道事件的创建过程:

internal override void BuildSteps(WaitCallback stepCallback)
{
ArrayList steps = new ArrayList();
HttpApplication app = base._application;
bool flag = false;
UrlMappingsSection urlMappings = RuntimeConfig.GetConfig().UrlMappings;
flag = urlMappings.IsEnabled && (urlMappings.UrlMappings.Count > 0);
steps.Add(new HttpApplication.ValidatePathExecutionStep(app));
if (flag)
{
steps.Add(new HttpApplication.UrlMappingsExecutionStep(app));
}
app.CreateEventExecutionSteps(HttpApplication.EventBeginRequest, steps);
app.CreateEventExecutionSteps(HttpApplication.EventAuthenticateRequest, steps);
app.CreateEventExecutionSteps(HttpApplication.EventDefaultAuthentication, steps);
app.CreateEventExecutionSteps(HttpApplication.EventPostAuthenticateRequest, steps);
app.CreateEventExecutionSteps(HttpApplication.EventAuthorizeRequest, steps);
app.CreateEventExecutionSteps(HttpApplication.EventPostAuthorizeRequest, steps);
app.CreateEventExecutionSteps(HttpApplication.EventResolveRequestCache, steps);
app.CreateEventExecutionSteps(HttpApplication.EventPostResolveRequestCache, steps);
steps.Add(new HttpApplication.MapHandlerExecutionStep(app));
app.CreateEventExecutionSteps(HttpApplication.EventPostMapRequestHandler, steps);
app.CreateEventExecutionSteps(HttpApplication.EventAcquireRequestState, steps);
app.CreateEventExecutionSteps(HttpApplication.EventPostAcquireRequestState, steps);
app.CreateEventExecutionSteps(HttpApplication.EventPreRequestHandlerExecute, steps);
steps.Add(new HttpApplication.CallHandlerExecutionStep(app)); //调用HttpHandler
app.CreateEventExecutionSteps(HttpApplication.EventPostRequestHandlerExecute, steps);
app.CreateEventExecutionSteps(HttpApplication.EventReleaseRequestState, steps);
app.CreateEventExecutionSteps(HttpApplication.EventPostReleaseRequestState, steps);
steps.Add(new HttpApplication.CallFilterExecutionStep(app));
app.CreateEventExecutionSteps(HttpApplication.EventUpdateRequestCache, steps);
app.CreateEventExecutionSteps(HttpApplication.EventPostUpdateRequestCache, steps);
this._endRequestStepIndex = steps.Count;
app.CreateEventExecutionSteps(HttpApplication.EventEndRequest, steps);
steps.Add(new HttpApplication.NoopExecutionStep());
this._execSteps = new HttpApplication.IExecutionStep[steps.Count];
steps.CopyTo(this._execSteps);
this._resumeStepsWaitCallback = stepCallback;
}

管道事件请求序列图如下:

ASP.NET是如何在IIS下工作的的更多相关文章

  1. ASP.NET是如何在IIS下工作的[转]

    ASP.NET与IIS是紧密联系的,由于IIS6.0与IIS7.0的工作方式的不同,导致ASP.NET的工作原理也发生了相应的变化. IIS6(IIS7的经典模式)与IIS7的集成模式的不同 IIS6 ...

  2. CityEngine Web Scene如何在IIS下部署 [转]

    CityEngine2012新增了发布Web场景的功能,可以通过本地的Web Scene Viewer打开,也可以发布到ArcGIS Online云端进行共享.如下图:   注:3ws场景包制作方法: ...

  3. 【.NET应用技巧】Asp.NET MVC 4 设置IIS下调试

    [环境] VS 2012  IIS7.5 [问题] MVC项目在创建时和APS.NET不同,不能够选择服务器类型,不能够直接把项目创建到IIS上. 如果在项目中直接更改属性,更换调试服务器类型,会报错 ...

  4. 中小研发团队架构实践之生产环境诊断工具WinDbg 三分钟学会.NET微服务之Polly 使用.Net Core+IView+Vue集成上传图片功能 Fiddler原理~知多少? ABP框架(asp.net core 2.X+Vue)模板项目学习之路(一) C#程序中设置全局代理(Global Proxy) WCF 4.0 使用说明 如何在IIS上发布,并能正常访问

    中小研发团队架构实践之生产环境诊断工具WinDbg 生产环境偶尔会出现一些异常问题,WinDbg或GDB是解决此类问题的利器.调试工具WinDbg如同医生的听诊器,是系统生病时做问题诊断的逆向分析工具 ...

  5. IIS下Asp.Net应用程序多进程设置及Session共享

    背景: 目前项目中在单个进程的应用程序经常会遇到w3c.exe崩溃的情况,于是就设想是否可以通过IIS多进程的方案来避免出现该问题. 于是搜了下“怎么实现多进程的方案”,找到了这篇文章:http:// ...

  6. 如何在IIS7下配置ASP+ACCESS环境

    如何在IIS7下配置ASP+ACCESS环境 | 浏览:901 | 更新:2013-01-16 17:46 1 2 3 4 5 6 7 分步阅读 默认装完IIS7之后,使用ASP程序会发现提示数据库连 ...

  7. 【转】各版本IIS下ASP.net请求处理过程区别

    原文地址:http://www.cnblogs.com/fsjohnhuang/articles/2332074.html ASP.NET是一个非常强大的构建Web应用的平台,它提供了极大的灵活性和能 ...

  8. IIS站点工作原理与ASP.NET工作原理

    IIS站点工作原理与ASP.NET工作原理  一.IIS IIS 7.0工作原理图 两种模式: 1.用户模式(User Mode)(运行用户的程序代码.限制在特定的范围内活动.有些操作必须要受到Ker ...

  9. 各版本IIS下ASP.net请求处理过程区别

      ASP.NET是一个非常强大的构建Web应用的平台,它提供了极大的灵活性和能力以致于可以用它来构建所有类型的Web应用. 绝大多数的人只熟悉高层的框架如: WebForms 和 WebServic ...

随机推荐

  1. 先说IEnumerable,我们每天用的foreach你真的懂它吗?

    我们先思考几个问题: 为什么在foreach中不能修改item的值? 要实现foreach需要满足什么条件? 为什么Linq to Object中要返回IEnumerable? 接下来,先开始我们的正 ...

  2. javascript中的this与函数讲解

    前言 javascript中没有块级作用域(es6以前),javascript中作用域分为函数作用域和全局作用域.并且,大家可以认为全局作用域其实就是Window函数的函数作用域,我们编写的js代码, ...

  3. 如何一步一步用DDD设计一个电商网站(五)—— 停下脚步,重新出发

    阅读目录 前言 单元测试 纠正错误,重新出发 结语 一.前言 实际编码已经写了2篇了,在这过程中非常感谢有听到观点不同的声音,借着这个契机,今天这篇就把大家提出的建议一个个的过一遍,重新整理,重新出发 ...

  4. 游戏编程系列[1]--游戏编程中RPC协议的使用[3]--体验

    运行环境,客户端一般编译为.Net 3.5 Unity兼容,服务端因为用了一些库,所以一般为4.0 或往上.同一份代码,建立拥有2个项目.客户端引用: WindNet.Client服务端引用: OpL ...

  5. iOS逆向工程之Theos

    如果你对iOS逆向工程有所了解,那么你对Tweak并不陌生.那么由Tweak我们又会引出Theos, 那么什么是Theos呢,简单一句话,Theos是一个越狱开发工具包,Theos是越狱开发工具的首先 ...

  6. 自定义搭建PHP开发环境

    学习了一段时间php了,因为之前是刚接触php,所以用的是集成安装包(wamp).现在想进一步了解apache.mysql.php之间的关系以及提升自己所以进行自定义搭建PHP开发环境.废话不多说,请 ...

  7. “fixed+relative==absolute”——对BFC的再次思考

    好久没写博客了,刚好今天跨年夜没约到什么妹子,在家宅着不如写点东西好了. 需求 昨天晚上,给公司年会做一个移动端的投票页面,遇到一个UI优化的问题: · 正文内容少于一屏时,投票提交按钮固定显示在页面 ...

  8. scala练习题1 基础知识

    1, 在scala REPL中输入3. 然后按下tab键,有哪些方法可以被调用? 24个方法可以被调用, 8个基本类型: 基本的操作符, 等:     2,在scala REPL中,计算3的平方根,然 ...

  9. Jqprint实现页面打印

    好些项目需要实现页面打印,特别是一些后台管理类系统,下面介绍一款轻量级的打印插件: 1.实现页面打印要引入jQuery和Jqprint.点击下载Jqprint插件 <script languag ...

  10. H3 BPM社区:流程开发者的学习交流平台

    企业上市有上市流程,融资扩充有融资流程,项目招投标有招投标流程,部门领导选拔有晋升流程,员工请假休假有请假流程,早起上班梳洗有符合自己习惯的流程--生活处处是流程,流程无处不在.但从信息化建设来说,企 ...