【asp源码栏目提醒】:以下是网学会员为您推荐的asp源码-ASPNet控件开发 一、IIS架构与HTTP请求处理流程 Windows操作系统中的 - 培训资料,希望本篇文章对您学习有所帮助。
ASP.Net控件开发 一、IIS架构与HTTP请求处理流程 Windows操作系统中的IIS负责提供互联网服务,一台运行了IIS的计算机可以看成是一台Web服务器。
Windows XP SP2 中IIS主版本号为5,Windows 2003 Server为6,Vista和Windows Server 2008为7。
对于Windows 2003 Server,其默认支持的
ASP.NET版本为1.1,因此必须单独安装.NET Framework 2.0以上版本lt--if supportFootnotes--gt1lt--endif--gt。
目前,IIS 6是使用最为广泛的版本,IIS 5已基本不在Web服务器上部署, IIS 6与IIS 5相比在系统架构上有着较大的差异,IIS 7与IIS 6相比,基本架构并没有根本性的变化,但在许多方面有新的增强和改进。
本书选择IIS 6/7进行介绍,大部分内容也适合于IIS 5,但IIS 5一些已过时的特性就不介绍了。
首先,我们来仔细分辨一下三个很容易混淆的基本概念。
1、网站、Web应用程序和虚拟目录 在IIS中可以创建网站、Web 应用程序和虚拟目录,以便与计算机网络上的用户共享信息。
“网站”、“Web 应用程序”和“虚拟目录”这三个概念的关系如图所示。
简而言之,一个“网站(Web Site)”包含一个或多个“ Web 应用程序(Web Application)”,一个Web 应用程序包含一个或多个“虚拟目录(Virtual Directory)”,而虚拟目录则映射到 Web 服务器或远程计算机上的物理目录。
图 82所示为运行IIS 7的一个Web服务器。
图所示为运行IIS 7的一个Web服务器。
图中可以清楚地看到此Web服务器上有两个“网站”:Default Web Site 和NewWebSite,其中Default Web Site网站中有三个“Web 应用程序”:HappyBookShopService、HappyBookShopWebSite和OnlineAlbum。
而HappyBookShopWebSite应用程序下的每一个子文件夹都是一个“虚拟目录”。
最顶层的虚拟目录称为“根虚拟目录”, 图 82中Web应用程序HappyBookShopWebSite的根虚拟目录为“/HappyBookShopWebSite”。
下面逐个剖析这三个概念。
1网站(Web Site) 网站是 Web 应用程序的容器,每个网站都有一个唯一的标识,这一标识由它的 IP 地址、端口和可选的主机头/主机名组合而成,Web服务器根据收到的HTTP请求中的这些信息来确定是对哪一个网站的请求 在IIS 7中,将网站标识称为“网站绑定”,图 83所示为IIS 7默认网站的“网站绑定”对话框。
Web 应用程序是一种在应用程序池(Application Pool)中运行并通过 HTTP 协议向用户提供信息服务(通常以HTML 格式表达信息)的软件程序。
创建 Web 应用程序时,Web 应用程序的名称将成为网站 URL 的一部分,用户可以通过 Web 浏览器发出针对该 URL的HTTP请求。
使用Visual Studio创建的“
ASP.NET网站”,其实是一个“Web 应用程序”,它并不等于IIS中的“网站”。
在 IIS中,每个网站至少必须拥有一个 Web 应用程序(但不一定是
ASP.NET应用程序,可以是其他类型的Web应用程序),它被称为“或“,除此之外,网站还可以包含一个或多个
ASP.NET(或其他种类) Web 应用程序。
在Windows XP SP2中,使用Visual Studio创建的
ASP.NET网站发布到本机IIS之后都是作为本机默认网站(即“localhost”所代表的网站)所承载的Web应用程序而运行的。
Windows Server和Vista可以为某个
ASP.NET应用程序创建一个独立的IIS网站,此网站只承载这个唯一的
ASP.NET应用程序,并且运行在一个独立的应用程序池中。
许多商业网站都采用这种方法以获取较高的性能,同时将此网站与Web服务器上承载的其他网站相互隔离,以增强Web服务器的安全性。
虚拟目录是在 IIS 中指定并映射到本地或远程服务器上的物理目录的目录名称。
然后,此虚拟目录名称将成为 Web 应用程序 URL 的一部分,用户可以通过 Web 浏览器向IIS请求访问此URL所对应的物理目录中的资源。
在 IIS中,每个 Web 应用程序都必须拥有一个最顶层的虚拟目录,它被称为“”。
在Visual Studio中,可以在属性窗口中直接设定
ASP.NET网站的根“虚拟路径”(图 84)。
但要注意,这里设定的“虚拟路径”是Visual Studio自带的轻量级Web服务器“
ASP.NET Development Server”的虚拟路径,而非IIS中的虚拟路径。
如果使用Visual Studio完整版本(比如团队开发版),则可以使用一个“发布网站”的功能。
在使用此功能发布网站时可以直接指定
ASP.NET应用程序在IIS中所对应的根虚拟目录 图 85中将
ASP.NET网站所对应的IIS根虚拟目录设为 MyNewWebSite。
一个Web 应用程序可以拥有多个虚拟目录,这些虚拟目录都将成为Web 应用程序根虚拟目录的子目录。
可以很方便地在IIS中创建一个虚拟目录 Web应用添加完虚拟目录之后,可以通过以下URL访问虚拟目录中的网页 例如: http://网站名称/Web应用程序根虚拟目录/新创建的子虚拟目录/Web网页名称 在上面的例子中,Web应用程序根虚拟目录为“/MyNewWebSite”,新加的虚拟目录为“MyNewVirtualDir”,它指向“D:MyDir”目录。
现假设D:MyDir目录中有一个
ASP.NET网页(不 妨设为Sample.aspx),则通过以下URL可以访问此网页: http://localhost/MyNewWebSite/MyNewVirtualDir/Sample.aspx 3、应用程序池与工作者进程 “应用程序池(Applicaion Pool)”是Windows Server为提升Web服务的性能和可靠性而引入的一个Web程序隔离机制。
一个应用程序池可包含一个或多个Web应用程序。
ASP.NET Web应用程序必须运行在一个应用程序池中。
在Windows Server中,一个或多个“工作者进程(Worker Process)”为应用程序池提供服务,停止一个应用程序池将导致这些工作者进程被关闭,这时,所有发往此应用程序池中Web应用程序的HTTP请求将收到“503服务不可用”的响应信息。
图 87展示了一台Web服务器上正在运行的应用程序池。
图 87 IIS 7中的应用程序池 如图 87所示,本台Web服务器上的设置了3个应用程序池,每个应用程序池中可运行多个Web应用程序,图中DefaultAppPool这一应用程序池运行了5个Web应用程序。
每个应用程序池都可以加载特定版本的.NET Framework,以对
ASP.NET应用程序提供支持。
在IIS 7中,应用程序池有两种运行模式——经典模式和集成模式。
经典模式下,IIS7应用程序池运行方式同IIS 6 1。
集成模式下,IIS 7直接预装载.NET Framework,从而为
ASP.NET应用程序提供了更好的性能。
在IIS管理器中可以随时启动和停止某个应用程序池。
Windows Server上运行应用程序池的系统帐号是“NetworkService”。
在后面的章节中可以看到在部署
ASP.NET网站时往往需要给此帐号设置特定的权限(比如允许
ASP.NET应用程序向某文件夹中添加文件)。
下面深入介绍一下IIS的系统架构以及Windows Server是如何响应HTTP请求的。
8.1.3 IIS的系统架构 IIS 6(运行于Windows 2003 Server)的架构如图 88所示。
图 88 IIS 6的架构 从图 88中可以看到,IIS 6架构由以下几个部分组成: (1)HTTP.SYS:运行于Windows核心(Kernel)的一个组件,它负责侦听(Listen)来自于外部的HTTP请求(通常来自网络中另一台计算机上的浏览器),根据请求的URL将其转发给相应的应用程序池,由运行于应用程序池中的工作者进程来响应此HTTP请求。
当此HTTP请求处理完成时,它又负责将处理结果发送出去(其接收者通常为发出HTTP请求的浏览器)。
为了提供更好的性能,HTTP.SYS内部建立了一个缓冲区,将最近的HTTP请求处理结果保存起来,如果发现某个HTTP请求“不久以前”处理过了(即在缓冲区中可以找到),它就简单地直接从缓冲区中取出这些结果发回给客户端(通常为发出HTTP请求的浏览 器)。
(2)InetInfo:在IIS 5时代,InetInfo是IIS服务的主进程,在IIS 6中,它不再负责处理HTTP请求,但它继续负责管理除了WWW服务之外的其他互联网服务,比如用于文件传输的FTP服务和用于邮件收发的SMTP服务。
InetInfo内部维护了一个元数据库(Metabase),在这个数据库中存入了一些重要的信息,这些信息对于维护各种互联网服务(比如WWW和FTP)等是必不可少的。
(3)Worker Process:负责处理HTTP请求,被译为“工作者进程”,事实上,它是由一个可执行程序W3WP.EXE运行时所生成的一个进程2,每一个工作者进程内部都可以管理一个或多个
ASP.NET应用程序。
工作者进程运行于一个应用程序池(Application Pool)中。
IIS 6可以创建多个应用程序池,并指定某个
ASP.NET应用程序在特定的应用程序池中运行(图 89)。
图 89 设定
ASP.NET网站所属的应用程序池(图截自Windows 2003 Server) 一般情况下,一个应用程序池只有一个工作者进程,但也可通过配置必要的参数让多个工作者进程同时运行在同一个应用程序池中,在这种情况下,这个应用程序池被称为“Web Garden(Web园)”。
(4)WAS(Web Admin Service):这是一个监控程序,它一方面可以存取放在InetInfo元数据库(Metabase)中的各种信息,另一方面也负责监控应用程序池(Application Pool)中的工作者进程的工作状态况,必要时它会关闭一个老的工作者进程并创建一个新的取而代之。
.1.4 HTTP 在了解了IIS的架构之后,来看一下IIS架构中的各个组成部分是如何相互配合处理HTTP请求的。
先来从总体上看看HTTP请求的处理过程(图 8-10)。
图 8-10 HTTP请求的处理过程 图 8-10清晰地展示出了HTTPWeb。
首先,浏览器尝试连接Web服务器的80端口,如果Web服务器可以响应此连接请求,就在浏览器与Web服务器间建立了一个通讯链路,在此“通道”上浏览器与Web服务器可以相互发送与接收信息。
假设浏览器向Web服务器发出一个读取某
ASP.NET站点上的某个ASPX网页的请求。
当此请求通过网络到达Web服务器时,此请求被HTTP.SYS组件所接收。
HTTP.SYS系统组件会检查此HTTP请求的相关信息,根据其URL将此HTTP请求发送给运行在某个应用程序池中的工作者进程处理。
如果同时有多个针对此
ASP.NET站点的HTTP请求,HTTP.SYS会将这些请求排队,加入到对应的应用程序池的HTTP请求队列中等待。
如果这是第一个对
ASP.NET站点的HTTP请求,工作者进程会加载aspnet_isapi.dll,并将请求转给它,aspnet_isapi.dll接着会装载.NET CLR1创建一个针对此
ASP.NET站点的应用程序域2,然后启动一个复杂的由多个步骤和组件参与的处理流程,当此处理流程结束,要发回给客户端的结果(通常是HTML代码,当然也可以是其他类型的资源,比如由程序动态生成的图片)已经生成,此结果被转发给HTTP.SYS。
对于以集成模式运行的IIS 7,.NET CLR在应用程序池一启动就自动装载,从而避免了临时装载CLR的花销。
后继处理过程与IIS 6基本一致。
HTTP.SYS接收到请求的处理结果之后,将其缓存到缓冲区中,然后把处理结果发回给发出HTTP请求的浏览器。
上述过程是对IIS处理HTTP请求全过程的粗略描述。
8.2节将选取这个处理过程中的主要阶段,详细介绍针对
ASP.NET网页的HTTP请求处理过程。
8.1.5 ISAPIISAPI 在IIS的文档中经常会提到两个术语:ISAPI扩展和ISAPI筛选器。
1 ISAPI “ISAPIISAPI Extension”是一种可以添加到IIS中以增强Web服务器功能的程序,其载体为DLL文件。
它通常直接负责响应HTTP请求。
根据HTTP请求要访问的资源扩展名(通过URL获取),IIS会选取特定的ISAPI扩展来处理这一请求,这一过程被称为“”。
而用于响应HTTP请求的这一ISAPI扩展被称为“”。
图 8-11展示了IIS 6中的程序映射。
图 8-11 程序映射(IIS 6) 在图 8-11中可以看到,IIS指定对
ASP.NET网页(其扩展名为.aspx)的请求将由aspnet_isapi.dll处理(图 8-12)。
图 8-12 aspnet_isapi.dll负责处理对
ASP.NET网页的请求 IIS 7中的程序映射与IIS 6略有不同。
当IIS 7以“经典模式”运行时,与IIS 6一样使用aspnet_isapi.dll响应针对“.aspx”的请求。
但当IIS 7以“集成模式”运行时,则使用托管处理程序(System.Web.UI.PageHandlerFactory)响应针对“.aspx”的请求(图 8-13)。
图 8-13 IIS 7集成模式下的程序映射 2 ISAPI “ISAPIISAPI Filter”也是一种DLL,但它不负责生成HTTP请求,它的主要作用是响应某些特定的事件。
当这些事件发生时ISAPI筛选器被调用,它可以修改传入或传出的HTTP数据。
在IIS 7中,使用“取代了传统ISAPI筛选器的功能。
ISAPI扩展与ISAPI筛选器名字很相近,但其在IIS中的地位和所起的作用是不同的。
Hosting 从本质上讲,
Asp.Net 主要是由一系列的类组成,这些类的主要目的就是将Http请求转变为对客户端的响应。
HttpRuntime类是
Asp.Net的一个主要入口,它有一个称作 ProcessRequest 的方法,这个方法以一个 HttpWorkerRequest 类作为参数。
HttpRuntime 类几乎包含着关于单个 Http请求的所有信息:所请求的文件、服务器端变量、QueryString、Http 头信息 等等。
Asp.Net 使用这些信息来加载、运行正确的文件,并且将这个请求转换到输出流中,一般来说,也就是HTML页面。
二般来说,也可以是张图片。
当 Web.config文件的内容发生改变 或者 .aspx文件发生变动的时候,为了能够卸载运行在同一个进程中的应用程序(卸载也是为了重新加载),Http请求被分放在相互隔离的应用程序域中。
可能你以前就听过应用程序域,但是不了解怎么回事,应用程序域就是 AppDomain。
对于IIS来说,它依赖一个叫做 HTTP.SYS 的内置驱动程序来监听来自外部的 HTTP请求。
在操作系统启动的时候,IIS首先在HTTP.SYS中注册自己的虚拟路径。
实际上相当于告诉HTTP.SYS哪些URL是可以访问的,哪些是不可以访问的。
举个简单的例子:为什么你访问不存在的文件会出现 404 错误呢?就是在这一步确定的。
如果请求的是一个可访问的URL,HTTP.SYS会将这个请求交给 IIS 工作者进程。
IIS6.0中叫做 w3wp.exe,IIS5.0中叫做 aspnet_wp.exe。
每个工作者进程都有一个身份标识 以及 一系列的可选性能参数。
可选性能参数,是指诸如 回收机制的设置、超时时间设置 等等。
这部分的内容相关性比较强,为了让大家好理解,我最后还是决定把 ISAPI 放到前面了,可能全系列完成的时候会再调整吧。
除了映射文件与其对应的处理程序以外,ISAPI 还需要做一些其他的工作: 1. 从HTTP.SYS中获取当前的Httq请求信息,并且将这些信息保存到 HttpWorkerRequest 类中。
2. 在相互隔离的应用程序域AppDomain中加载HttpRuntime。
3. 调用 HttpRuntime的ProcessRequest方法。
接下来才是程序员通常编写的代码所完成的工作了,然后,IIS 接收返回的数据流,并重新返还给 HTTP.SYS,最后,HTTP.SYS 再将这些数据返回给客户端浏览器。
OK,现在你看到张子阳的空间主页了。
Pipeline 在前面两章中,我们在一个相对比较低的层次上讨论了从发出Http请求到看到浏览器输出这转瞬即逝的十分之一秒内IIS和 Framework 所做的事情。
但是我们忽略了一个细节:程序员编写的代码是如何在这一过程中衔接的,本章我们就来看看这个问题。
当Http请求进入
Asp.Net Runtime以后,它的管道由托管模块(NOTE:Managed Modules)和处理程序(NOTE:Handlers)组成,并且由管道来处理这个 Http请求。
我们按编号来看一下这幅图中的数据是如何流动的。
1. HttpRuntime将Http请求转交给 HttpApplication,HttpApplication代表着程序员创建的Web应用程序。
HttpApplication创建针对此Http请求的 HttpContext对象,这些对象包含了关于此请求的诸多其他对象,主要是HttpRequest、HttpResponse、HttpSessionState等。
这些对象在程序中可以通过Page类或者Context类进行访问。
、 2. 接下来Http请求通过一系列Module,这些Module对Http请求具有完全的控制权。
。
3. Http请求经过所有的Module之后,它会被HttpHandler处理。
在这一步,执行实际的一些操作,通常也就是.aspx页面所完成的业务逻辑。
可能你会觉得在创建.aspx页面并没有体会到这一过程,但是,你一定知道,.aspx 页面继承自Page类,我们看一下Page类的签名: public class Page : TemplateControl IHttpHandler // 代码省略 可以看到,Page类实现了IHttpHandler接口,HttpHandler也是Http请求处理的最底层。
4.HttpHandler处理完以后,Http请求再一次回到Module, 注意我用红色标识的字,然后回想一下:
Asp.Net 中是不是有众多的 Inserting 、Inserted 之类成对的事件?其实,这里讲述的就是为什么
Asp.Net可以将一个Insert操作分成前后两部分,然后再分别进行事件拦截的幕后原理。
如果我们将注意力只集中在Http请求、HttpHandler和HttpModule上,不去考虑HttpContext和HttpApplication,那么图4.可以简化成下面这样: 相信大家都使用过
ASP.NET进行过基于Web的应用开发
ASP.NET是什么?如果站在一个相对High Level的角度,我们可以这样来定义
ASP.NET:
ASP.NETWebServiceProgramming ModelSoftwareInfrastructure。
如果我们以一个Low Level的角度来看,它本质上就是一个消息处理器:他接受IIS(确切地说应该是
ASP.NET ISAPI)Forward的Http Request (我们可以看成是一个Request Message),经过一系列的处理,最终产生一个用户希望的Response(这也是一个Message,对于.aspx Page来说是一个Html document,对于一个Web Service来说是一个Soap)。
所以本篇文章的主要目的在于站在一个相对Low Level的角度介绍
ASP.NET的整个Http Request Processing Model。
我们访问一个基于
ASP.NET的资源,IIS是第一道屏障,在第一个部分我分别就IIS 5.x和IIS 6的差异介绍了IIS对Http Request的处理,今天我们来继续后面的故事。
上一部分我们说到IIS收到一个基于
ASP.NET资源文件的访问,它会把Http Request交给一个
ASP.NET ISAPI Extension处理。
ASP.NET ISAPI 会加载CLR,从而创建一个托管的环境。
ASP.NET ISAPI Extension定义在一个名为aspnet_isapi.dll中,aspnet_isapi.dll是一个纯Native的、高效的Dll,也就是说,虽然
ASP.NET ISAPI通过加载CLR创建一个托管 的环境,但是
ASP.NET ISAPI本省却运行在一个Unmanaged的环境中。
而我们的
ASP.NET Application确是完全的Managed code,运行在一个Managed的环境中。
要了解
ASP.NET Http Runtime Pipeline这个纯托管的Runtime,我们必须先了解从Unmanaged Environment到Managed Environment的这道桥梁。
上图简单表述了在IIS 6环境下,从非托管环境到托管环境的过程。
从图中我们可以看到,
ASP.NET ISAPI运行在一个非托管环境之中。
ASP.NET ISAPI经过系列COM级别的class调用(由于这些被调用的Class都是一个个undocumented class,所以要真正说清楚调用流程中每个具体的细节是一件很难的事情,而且也确实没有很大的必要去挖掘它,因为具体的实现可能会经常变动,如果对此具有好奇心的朋友可以通过一些Tool,比如Reflector去仔细研究一下),最终的调用降临到一个托管的、继承自System.Web.Hosting.ISAPIRuntime类的对象上。
ISAPIRuntime 是一个特殊的class,他实现了Interface System.Web.Hosting.IISAPIRuntime。
下面是该Interface的定义。
通过定义我们可以看到,这是一个基于COM的Interface,也就是说Caller可以通过COM的方式调用实现该Interface的Class的对象。
在这里,这个最初的Caller就是
ASP.NET ISAPI。
从这里我们可以总结出:
ASP.NET ISAPI通过调用System.Web.Hosting.ISAPIRuntime Instance的ProcessRequest方法,进而从非托管的环境进入了托管的环境。
ComImport InterfaceTypeComInterfaceType.InterfaceIsIUnknown Guidquot08a2c56f-7c16-41c1-a8be-432917a1a2d1quot public interface IISAPIRuntime void StartProcessing void StopProcessing return: MarshalAsUnmanagedType.I4 int ProcessRequestIn IntPtr ecb In MarshalAsUnmanagedType.I4 int useProcessModel void DoGCCollect ISAPI ECB Execution Control Block amp ISAPIWorkerRequest 通过System.Web.Hosting.IISAPIRuntime Interface中的ProcessRequest方法的Siganature,我们可以看出该方法包含两个参数,其中一个是名为ecb的Unmanaged Pointer,另一个是useProcessModel。
ECB全称是Execution Control Block,在整个Http Request Processing过程中起着非常重要的作用,我们现在来简单介绍一个ECB。
ISAPI顾名思义,就是实现了一些基于Internet Server的API。
Aspnet_isapi.dll实现了这些API,对于IIS来说,它可以调用这些API进入托管的环境实现对ISAPIRuntime的调用,对于ISAPIRuntime来说,它需要调用
ASP.NET ISAPI实现一些必要的功能,比如获得Server Variable的数据,获得通过Post Mehod传回Server的数据;以及最终将Response的内容返回给
ASP.NET ISAPI,并通过
ASP.NET ISAPI返回到Client。
一般地ISAPIRuntime不能直接调用
ASP.NET ISAPI,而是通过一个对象指针实现对其的调用,这个对象就是ECB,ECB实现了对ISAPI的访问。
还有一点特别需要强调的是,ISAPIISAPIRutime,也就是说ISAPI调用ISAPIRutime之后立即返回。
这主要是出于Performance和Responsibility考虑的,因为
ASP.NET Application天生就是一个多线程的应用,为了具有更好的响应能力,异步操作是最有效的解决方式。
但是这里就会有一个问题,我们知道我们对
ASP.NET 资源的调用本质上是一.
上一篇:
ASP NET导出页面到word程序说明文档
下一篇:
秋天是疼痛的