IIS是如何处理ASP.NET请求的

英文原文:Beginner’s Guide: How IIS Process ASP.NET Requestlinux

  前言程序员

  每次服务器接受到请求,都要先经IIS处理。这不是一篇描述ASP.NE生命周期的文章,仅仅是关于IIS操做的。在咱们开始以前,先了解这些会有助于对全文的理解,同时欢迎反馈和建议。api

  什么是Web Server?浏览器

  每当咱们经过VS运行ASP.NET网站时,VS集成的ASP.NET引擎会响应各类请求,这个引擎的名字叫“WebDev.WebServer.exe”。服务器

  当咱们配置一个Web程序时,总会涉及到一个词“Web Server”,它的功能即是会响应全部请求。asp.net

  什么是IIS?ide

  IIS(Internet Information Server)是微软Web Server的一种,用来配置ASP.NET站点。IIS拥有本身的ASP.NET处理引擎来处理请求,所以,当一个请求到达时,IIS接收并处理请求,而后返回内容。性能

  请求处理过程学习

  如今,你应能搞清楚Web Server和IIS的区别。如今咱们来看一下核心部分。在继续以前,你须要搞清两个概念:网站

  一、工做进程(Worker Process)

  二、应用程序池(Application Pool)

  工做进程:在IIS中,工做进程(w3wp.exe)运行着ASP.NET应用程序,管理并响应全部的请求,ASP.NET全部的功能都运行在工做进程下,当请求到来时,工做进程会生成Request和Response相关的信息。简而言之,工做进程就是ASP.NET程序的心脏。

  应用程序池:应用程序池是工做进程的容器,一般用来隔开不一样配置的工做进程。当一个程序出错或进程资源回收时,其余池中的程序不会受到影响。

  注:当一个应用程序池包含多个工做进程时,被叫作“Web Garden”。

  若是咱们看一下IIS 6.0的结构,就会发现,能够把它分红两部分:

  一、内核模块(Kernel Mode)

  二、用户模块(User Mode)

  内核模式是从IIS 6.0被引入的,它包含了一个叫HTTP.SYS的文件,每当请求进来时,会首先触发该文件的响应。

  HTTP.SYS文件负责把请求传入相应的应用程序池中。但HTTP.SYS如何知道应传给哪一个应用程序池呢?固然不是随机抽取,每当建立一个应用程序池,该池的ID就会生成并在HTTP.SYS文件中注册,所以该文件才能肯定将请求往哪传。

  以上即是IIS处理请求的第一步。接着,咱们来看一下请求如何从HTTP.SYS传入应用程序池。

  在IIS的用户模块中,经过Web Admin Services (WAS)从HTTP.SYS接收请求,并传入相应的应用程序池中。

  当应用程序池接收到请求,会接着传给工做进程(w3wp.exe),该进程检查来请求的URL后缀以肯定加载哪一个ISAPI扩展。ASP.NET加载时会附带本身的ISAPI扩展(aspnet_isapi.dll),以便在IIS中映射。

  注意:若是先安装了asp.net,而后再安装IIS,就须要经过aspnet_regiis命令来注册ASP.NET中的ISAPI扩展。

  一旦工做进程加载了aspnet_isapi.dll, 就会构造一个HttpRuntime类,该类是应用程序的入口,经过ProcessRequest方法处理请求。

  一旦这个方法被调用,一个HttpContext的实例就产生了。可经过HTTPContent.Current获取到这个实例,且该实例会在整个生命周期中存活,咱们经过它能够获取到一些经常使用对象,如Request,Response,Session 等。

  以后HttpRuntime会经过HttpApplicationFactory类加载一个HttpApplication对象。每一次请求都要穿过一堆HttpModule到达HttpHandler,以便被响应。而这些HttpModule就被配置在HttpApplication中。

  有一个概念叫“Http管道”,被叫作管道是由于它包含了一系列的HttpModule,这些HttpModule拦截请求并将其导向相应的HttpHandler。咱们也可自定义HttpModule,以便在请求响应之间作点特别的处理。

  HttpHandler是“Http管道”的终点。全部请求穿过HttpModule需抵达相应的HttpHandler,而后HttpHandler根据请求资源,产生并输出内容。也正所以,咱们请求任何aspx页面才会获得响应的Html内容。

  结语

  每当请求Web服务器上的某些信息时,该请求首先会到达Http.SYS, 而后Http.SYS将其发送到相应的应用程序池,应用程序池传给工做进程并加载ISAPI扩展,而后HttpRuntime对象会被建立,并经过HttpModule和HttpHandler处理请求。

  最后,ASP.NET页面生命周期就开始了。

  这只是大体描述IIS处理过程的文章,若是你想进一步了解相应细节,请点击下面连接来进一步学习。

  A low-level Look at the ASP.NET Architecture

  IIS Architecture

  本文翻译自:Beginner’s Guide: How IIS Process ASP.NET Request

  译后小注:

  一、若是在IIS配置完站点却看不到“w3wp.exe”进程,只要用浏览器打开该站其中一个页面,“w3wp.exe”进程就会出现了。

  二、为节省时间,直接引用了原图,英文差的,小查一下字典应该没啥问题。

 

Http请求处理流程概述

 

思考“为何在地址栏输入www.tracefact.net就能够看到张子阳的我的空间?”,相似于思考“为何苹果是往地上掉不是往天上飘?”。对于普通访问者来讲,这就像天天太阳东边升起西边落下同样是理所固然的;对于不少程序员来讲,认为这个与己无关,不过是系统管理员或者网管员的责任。毕竟,IIS是 Windows 的一个组件,又不是 Asp.Net 的一个组成部分。而实际上,从你轻拍回车到页面呈如今你眼前的十分之一秒内,IIS和.Net Framework已经作了大量的幕后工做。

你可能以为了解这些幕后工做是如何运做的可有可无,做为程序员的你只要保证开发出的程序能够高效地运行就能够了。然而,在开发过程当中,你却发现经常须要使用诸如 HttpContext 这样的类。这个时候,你可曾思考过这些类的构成和类的实体是如何建立的?你可能简单地回答:HttpContext表明当前请求的一个上下文环境。可你又知道IIS 、Framework、Asp.Net 是如何协同工做处理每一个Http请求、如何区分不一样的请求、IIS、Framework、Asp.Net三者之间的数据如何流动么?

回答上面这些问题,首先须要了解IIS是如何处理页面请求的,这也是理解 Form验证模式和Windows 验证模式 的基础。

Http请求刚刚到达服务器的时候

当服务器接收到一个 Http请求的时候,IIS 首先须要决定如何去处理这个请求(NOTE:服务器处理一个.htm页面和一个.aspx页面确定是不同的么)。那IIS依据什么去处理呢?―― 根据文件的后缀名。

服务器获取所请求的页面(NOTE:也能够是文件,好比 jimmy.jpg)的后缀名之后,接下来会在服务器端寻找能够处理这类后缀名的应用程序,若是IIS找不到能够处理此类文件的应用程序,而且这个文件也没有受到服务器端的保护(NOTE:一个受保护的例子就是 App_Code中的文件,一个不受保护的例子就是你的js脚本),那么IIS将直接把这个文件返还给客户端。

可以处理各类后缀名的应用程序,一般被称为 ISAPI 应用程序(NOTE:Internet Server Application Programe Interface,互联网服务器应用程序接口)。虽然这 ISAPI 听上去还挺气派,也算是“应用程序”呢,但仔细看看它的全称就明白了:它实际上只是一个接口,起到一个代理的做用,它的主要工做是映射所请求的页面(文件)  和与此后缀名相对应的实际的处理程序。

让咱们更进一步地看一下 ISAPI ,看看它究竟是什么样子,请按下面的步骤进行:

  1. 打开IIS。
  2. 选择随意一个站点,鼠标右键,“属性”。
  3. 选择“主目录”选项卡。
  4. 选择“配置”。

你应该会看到以下的画面:

图1. 应用程序配置

很清楚地就能够看到,全部IIS所能处理,或者叫 ISAPI 所提供代理服务的 文件类型 及其相对应的实际的后台处理程序都在这里清楚地列出来了。

咱们找到 .aspx 的应用处理程序,而后点“编辑”,会出现下面的画面:

图2. 编辑.aspx文件的处理程序

 

一路看到这里,能够看出,全部的.aspx文件实际上都是由 aspnet_isapi.dll 这个程序来处理的,当IIS把对于.aspx页面的请求提交给了aspnet_isapi.dll之后,它就再也不关心这个请求随后是如何处理的了。如今咱们应该知道:Asp.Net 只是服务器(IIS)的一个组成部分而已,它是一个 ISAPI扩展。

这里须要注意两点:

  • 当你修改“限制为”后,能够限制页面(文件)只能以某种特定方式访问
  • “确认文件是否存在”是实现 URL 地址映射的关键选项,我之后会专门讲述。

理解宿主环境(Hosting)

从本质上讲,Asp.Net 主要是由一系列的类组成,这些类的主要目的就是将Http请求转变为对客户端的响应。HttpRuntime类是Asp.Net的一个主要入口,它有一个称做 ProcessRequest 的方法,这个方法以一个 HttpWorkerRequest 类做为参数。HttpRuntime 类几乎包含着关于单个 Http请求的全部信息:所请求的文件、服务器端变量、QueryString、Http 头信息 等等。Asp.Net 使用这些信息来加载、运行正确的文件,而且将这个请求转换到输出流中,通常来讲,也就是HTML页面。

NOTE:二般来讲,也能够是张图片。

当 Web.config文件的内容发生改变 或者 .aspx文件发生变更的时候,为了可以卸载运行在同一个进程中的应用程序(NOTE:卸载也是为了从新加载),Http请求被分放在相互隔离的应用程序域中。

NOTE:可能你之前就听过应用程序域,可是不了解怎么回事,应用程序域就是 AppDomain。

对于IIS来讲,它依赖一个叫作 HTTP.SYS 的内置驱动程序来监听来自外部的 HTTP请求。在操做系统启动的时候,IIS首先在HTTP.SYS中注册本身的虚拟路径。

NOTE:实际上至关于告诉HTTP.SYS哪些URL是能够访问的,哪些是不能够访问的。举个简单的例子:为何你访问不存在的文件会出现 404 错误呢?就是在这一步肯定的。

若是请求的是一个可访问的URL,HTTP.SYS会将这个请求交给 IIS 工做者进程。

NOTE:IIS6.0中叫作 w3wp.exe,IIS5.0中叫作 aspnet_wp.exe。

每一个工做者进程都有一个身份标识 以及 一系列的可选性能参数。

NOTE:可选性能参数,是指诸如 回收机制的设置、超时时间设置 等等。

接下来进行的事情就是上一章节讲述的 ISAPI 了。

NOTE:这部分的内容相关性比较强,为了让你们好理解,我最后仍是决定把 ISAPI 放到前面了,可能全系列完成的时候会再调整吧。

除了映射文件与其对应的处理程序之外,ISAPI 还须要作一些其余的工做:

  1. 从HTTP.SYS中获取当前的Httq请求信息,而且将这些信息保存到 HttpWorkerRequest 类中。
  2. 在相互隔离的应用程序域AppDomain中加载HttpRuntime。
  3. 调用 HttpRuntime的ProcessRequest方法。

接下来才是程序员一般编写的代码所完成的工做了,而后,IIS 接收返回的数据流,并从新返还给 HTTP.SYS,最后,HTTP.SYS 再将这些数据返回给客户端浏览器。

OK,如今你看到张子阳的空间主页了。

图3.Asp.Net 的宿主环境

理解管道(Pipeline)

在前面两章中,咱们在一个相对比较低的层次上讨论了从发出Http请求到看到浏览器输出这转瞬即逝的十分之一秒内IIS和 Framework 所作的事情。可是咱们忽略了一个细节:程序员编写的代码是如何在这一过程当中衔接的,本章咱们就来看看这个问题。

当Http请求进入 Asp.Net Runtime之后,它的管道由托管模块(NOTE:Managed Modules)和处理程序(NOTE:Handlers)组成,而且由管道来处理这个 Http请求。

图4. 理解 Http 管道

咱们按编号来看一下这幅图中的数据是如何流动的。

1. HttpRuntime将Http请求转交给 HttpApplication,HttpApplication表明着程序员建立的Web应用程序。HttpApplication建立针对此Http请求的 HttpContext对象,这些对象包含了关于此请求的诸多其余对象,主要是HttpRequest、HttpResponse、HttpSessionState等。这些对象在程序中能够经过Page类或者Context类进行访问。、

2. 接下来Http请求经过一系列Module,这些Module对Http请求具备彻底的控制权。这些Module能够作一些执行某个实际工做前的事情。

3. Http请求通过全部的Module以后,它会被HttpHandler处理。在这一步,执行实际的一些操做,一般也就是.aspx页面所完成的业务逻辑。可能你会以为在建立.aspx页面并无体会到这一过程,可是,你必定知道,.aspx 页面继承自Page类,咱们看一下Page类的签名:

public class Page : TemplateControl, IHttpHandler{
    // 代码省略
}

能够看到,Page类实现了IHttpHandler接口,HttpHandler也是Http请求处理的最底层。

4.HttpHandler处理完之后,Http请求再一次回到Module,此时Module能够作一些某个工做已经完成了以后的事情。

NOTE:注意我用红色标识的字,而后回想一下:Asp.Net 中是否是有众多的 Inserting 、Inserted 之类成对的事件?其实,这里讲述的就是为何Asp.Net能够将一个Insert操做分红先后两部分,而后再分别进行事件拦截的幕后原理。

若是咱们将注意力只集中在Http请求、HttpHandler和HttpModule上,不去考虑HttpContext和HttpApplication,那么图4.能够简化成下面这样:

图5.Http请求在HttpHandler 和 HttpModule 中的流动方向

 

本文连接转自:http://blog.csdn.net/linux7985/article/details/44079993

相关文章
相关标签/搜索