Asp.net管道模型(管线模型)之一发不可收拾

前言                                

  为什么我会起这样的一个标题,其实我原本只想了解asp.net的管道模型而已,但在查看资料的时候遇到不明白的地方又横向地查阅了其他相关的资料,而收获比当初预想的大了很多。

  有本篇作基础,下面两篇就更好理解了:

  理解并自定义HttpHandler

  理解并自定义HttpModule

目录                                

  一般不写目录,感觉这次要写的东西有些多就写一个清晰一下吧。

  1.Asp.net管道模型

  2.进程的子进程与进程的线程

  3.应用程序域(AppDomain)

  4.IIS5.x下一个HTTP请求/响应过程的整体框架

  5.IIS5.x、IIS6.x和IIS7.x的区别

Asp.net管道模型                        

  参考:ASP.NET使用管道模型(PipleLines)处理HTTP请求

          HttpRuntime的认识与加深理解

          HttpModule的认识(转载)

  管道模型中包含以下对象:

流程图:

  Http
Request传到工作进程(IIS5.x为aspnet_wp.exe,IIS6.x和IIS7.x为w3wp.exe)后,工作进程实例中通过
ISAPIRuntime(主要作用是调用一些非托管代码生成HttpWorkerRequest对象,HttpWorkerRequest对象包含当前
请求的所有信息,然后传递给HttpRuntime)传递HttpWorkerRequest对象给HttpRuntime并调用HttpRuntime
的ProcessRequest方法,HttpRuntime为管道模型的入口此时正式进入管道模型。   

  HttpRuntime根据HttpWorkerRequest对象生成HttpContext,HttpContext包含request、
response等属性,
再调用HttpApplicationFactory的GetApplicationInstance方法生成HttpApplication,
HttpApplication对象包含多个HttpModule对象(当一个HTTP请求到达HttpModule时,整个ASP.NET
Framework系统还并没有对这个HTTP请求做任何处理,也就是说此时对于HTTP请求来讲,HttpModule是一个HTTP请求的“必经之
路”,所以可以在这个HTTP请求传递到真正的请求处理中心(HttpHandler)之前附加一些需要的信息在这个HTTP请求信息之上,或者针对截获
的这个HTTP请求信息作一些额外的工作,或者在某些情况下干脆终止满足一些条件的HTTP请求,从而可以起到一个Filter过滤器的作用),并调用各
个HttpModule对象的Init方法初始化HttpModule,在Init方法中可以订阅HttpApplication的事件从而作出相应的处
理。当HttpApplication执行到Application_ResolveRequestCache时暂时将控制权交给HttpHandler
并根据HttpHandler中是否启用SessionState来确定是否生成会话跟踪功能(.aspx中用enablesessionstate设
置,.ashx中用是否继承IRequiresSessionState接口来设置),然后HttpApplication继续执行自身的事件直到执行完
PreRequestHandlerExecute事件就根据URL请求的后缀名获取HttpHandlerFactory对象(默认情况下.aspx调
用System.Web.UI.PageHandlerFactory,.ashx调用
System.Web.UI.SimpleHandlerFactory),调用HttpHandlerFactory的GetHandler方法生成具
体的HttpHandler对象或调用ReleaseHandler方法使工厂可以重用现有的处理程序实例来处理http请求并返回http响应,再经过
HttpApplication对象的一系列事件(具体事件请参考HttpModule的认识(转载))最终返回到客户端,当然http响应所经过的HttpApplication的一系列事件都可以被HttpModule对象所订阅。

 

进程的子进程与进程的线程                 

  参考:百度问答

  我拿Windows举例子吧, 因为Linux的内核好像是没有线程概念的.进程和线程的区别在于粒度不同,
进程之间的变量(或者说是内存)是不能直接互相访问的, 而线程可以, 线程一定会依附在某一个进程上执行.我举个例子,
你在Windows下开一个IE浏览器, 这个IE浏览器是一个进程. 你用浏览器去打开一个pdf, IE就去调用Acrobat去打开,
这时Acrobat是一个独立的进程, 就是IE的子进程.而IE自己本身同时用同一个进程开了2个网页, 并且同时在跑两个网页上的脚本,
这两个网页的执行就是IE自己通过两个线程实现的.值得注意的是, 线程仍然是IE的内容, 而子进程Acrobat严格来说就不属于IE了,
是另外一个程序.之所以是IE的子进程, 只是受IE调用而启动的而已.

追问:那我可不可以这样理解,父进程创建了一个子进程,只要给这个子进程分配一定的任务,他们从此就没有关系了 。。。。

回答:也不能这么说从此就没关系了, 父进程还是可以通过和子进程通信来获得一些信息的. 拿上面的例子来说,

IE可以通过一些进程间通信的接口来知道Acrobat是否顺利的把pdf打开了之类的信息. 但有一点我觉得你的理解基本正确,

就是父进程和子进程是独立的. 假如IE开了一个病毒子进程, 子进程不听话, 父进程也没什么特别的办法, 除了向系统申请去关闭它之外.

区分子进程和线程很简单:
一个独立程序的运行称为一个进程, 在进程里并发执行的不同部分称为线程. 由这个进程引发的另外的独立程序运行为这个进程的子进程. 
(基本上就是这样, 更加严格的定义建议参考操作系统的教科书)
  参考:.NET简谈组件程序设计之(AppDomain应用程序域)
  参考:http://blog.csdn.net/zhoufoxcn/article/details/2425420中周公的回答
  进程:属于操作系统上的概念,一个进程占有一个内存地址,是应用程序与应用程序之间的边界,进程之间不能共享代码和数据空间(也就是不能直接交互),但可以通过IPC(remoting、named pipe、webservice等)进行数据交互。一个进程出现错误甚至崩溃不会影响其他进程的执行。
  子进程:由另一个进程启动,子进程与父进程没有从属关系,两进程可以通过IPC进行数据交互。
  线程:属于操作系统上的概念,是代码执行堆栈和执行上下文的边界,同一进程的多个线程共享代码和数据空间,但只负责执行代码而没有携带数据的功能。独立或多个线程协同负责执行进程中的任务。
  题外:对于线程其实还有很多方面可以深入,更多请参考《深入线程

应用程序域(AppDomain)                  
参考:理解AppDomain
  AppDomain是.net framework独有的概念,是逻辑宿主,其功能就像进程那样是程序运行的独立空间(从进程中分配独立的内存空间,AppDomain间不能共享代码和数据空间),当一个AppDomain中的程序出现异常甚至崩溃时不会影响到其他AppDomain中运行的程序。但AppDomain不是进程,一个进程可以拥有一个或多个AppDomain,其中必须有一个默认的AppDomain。
  也许这里您会有这样的疑问:AppDomain是线程吗?如果不是那么与线程的关系是什么呢?在.net framework中存在进程、应用程序域(AppDomain)、线程三个独立又有联系的概念,一个进程含一个或多个AppDomain(必须存在一个默认AppDomain);一个进程含一个或多个线程(通常含一个线程池,里面有多个可重用的线程);AppDomain与线程是多对多关系,但某一个时刻一个线程只能处理一个AppDomain,而AppDomain可以由多个线程同时处理(并发)。
  从运行程序时的过程是这样的:系统首先分配一段内存地址空间然后把控制权交给了CLR生成默认AppDomain,然后将程序集加载到默认AppDomain中,程序正式运行(系统在托管堆中没有AppDomain的概念,AppDomain不是操作系统的概念,由CLR管理)。默认AppDomain随CLR而生而亡,无法以编码方式删除或者卸载其中的程序集。
  下面以图的形式描述进程、线程、AppDomain的位置关系。

   AppDomain之间不能直接交互,可通过代理的方式进行数据交互(如果是进程就使用IPC)。(具体实现以后探讨!)

IIS5.x下一个HTTP请求/响应过程的整体框架            

 

  

  上图左边为IIS5.X WEB SERVER,右边为Asp.net Application的工作进程(worker process),Asp.net是以作为IIS组件的形式扩展IIS的。

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

   当一个http
request发送到IIS5.X时,IIS先把虚拟目录转变为物理目录,然后根据文件后缀名检查iis中的metabase文件检查文件扩展名与可执行
代码(扩展程序)映射记录(如.aspx、.ashx等对应aspnet_isapi.dll),如果metabase文件中没有就再检查是否为不受服务
器端保护的文件(受服务器端保护:App_Code文件夹下的文件;不受服务器端保护:css、js文件),如果都不存在则直接返回404HTTP状态码
给客户端;(该查找循序可通过《理解并自定HttpHandler》)存在则iis的inetinfo.exe实例会调用相应的可执行代码(这里是aspnet_isapi.dll),aspnet_isapi.dll会通过一个命名管道(named pipe,一种简单的IPC——进程通信机制,具体内容请参考:《命名管道及延伸进程通信学习》)
把从inetinfo.exe获取的request异步转发到Asp.net工作进程实例:aspnet_wp.exe,然后就进入管道模型。同时
aspnet_isapi.dll通过named
pipe监测工作进程的运行状况,如果工作进程性能低于某个值aspnet_isapi.exe就会杀死工作进程,当下一个请求传递过来时重新启动一个工
作进程处理请求。而工作进程通过named pipe同步请求web server的信息(如调用Server对象获取服务器信息)。

图依然秉承着我很丑但很有用的原则,嘻嘻!!
  aspnet_wp.exe的工作进程中含有一个线程池和一个默认AppDomain,当一个Request发送到工作进程后,工作进程会根据请求的虚拟目录的文件(一个虚拟目录对应一个Application)由默认AppDomain创建AppDomain并将该虚拟目录的程序集加载到AppDomain中(虚拟目录中可能不止一个程序集,而默认AppDomain会将整个虚拟目录下的所有程序集加载到AppDomain上),如果该虚拟目录的AppDomain已存在就直接使用该AppDomain,如果虚拟目录的程序集发生变化(包括web.config变化),就会新建一个AppDomain再将以变化的程序集加载到新的AppDomain中;这时从线程池获取空闲线程执行程序集(写一个网站发布成两个虚拟目录进行测试,可以看到执行http请求处理的线程不断地变化,两个虚拟目录会出现使用相同线程的情况)。程序集中的变量和状态均保存在所属的AppDomain的内存中,如HttpContext.Current.Items、Application等(Application对象其实就是一张HashTable,可以被多个线程(iis5.X)或多个Application实例(iis6.x)访问),AppDomain之间不能直接访问对方的变量和状态。Session状态变量有三种模式InProc、StateServer和SQLServer,其中默认为InProc表示Session状态保存在Asp.net进程中,如果虚拟目录的程序集发生变化后在新AppDomain中调用之前所设置的Session状态变量就会发现Session丢失了(客户端的Cookie中保存的SessionID依旧,如果存在应该是可以读取的),表明Session模式为InProc时Session状态变量保存在对应的AppDomain中。
  题外话:如果session模式设置为StateServer表示使用状态服务器保存Session状态,就是使用另外一个本地或远程进程来保存Session状态,本地开启状态服务器步骤(系统为Windows server类型):1.开始->所有程序->管理工具->服务->开启 Asp.net状态服务,然后配置一下网站的web.config为<sessionState mode="StateServer" stateConnectionString="tcpip=localhost:4242"/>
 
IIS5.x、IIS6.x和IIS7.x的区别                 
  参考:各版本IIS下ASP.net请求处理过程区别
  IIS5.x设计为一个服务器只启用一个工作进程来处理所有请求/响应,为保证各个Application(以虚拟目录为单位)独立运行且不干扰其他Application(一个Application崩溃不导致整个进程崩溃),引入了AppDomain。但AppDomain效果差强人意,于是IIS6.x开始使用应用程序池(Application Pool)。在非Web Garden模式下一个Application对应一个应用程序池,对应一个工作进程,6.x开始工作进程从Aspnet_wp改为w3wp;在Web Garden模式下一个Application对应一个应用程序池,对应多个工作进程,Application可以在任意一个工作进程上执行,一旦其中一个工作进程崩溃也能及时处理该Application的请求,但在Web Garden模式下SessionState不能使用InProc模式,因为该模式会将SessionState保存在工作进程的AppDomain中。
  IIS5.x中识别请求属于哪个Application是在工作进程中在用户模式下实现的,而IIS6.x是由Web Server的http.sys在核心模式实现的(IIS5.x的是Aspnet_isapi.dll,而IIS6.x开始使用了新组件http.sys)。注:为了避免用户应用程序访问或者修改关键的操作系统数据,windows提供了两种处理器访问模式:用户模式(User Mode)和内核模式(Kernel Mode)。一般地,用户程序运行在User mode下,而操作系统代码运行在Kernel Mode下。Kernel Mode的代码允许访问所有系统内存和所有CPU指令。
 IIS5.x和IIS6.x的ASP.NET都是以IIS ISAPI extension的方式外加到IIS,而IIS7.x开始把Asp.net继承到IIS当中,并且IIS7.x工作模式有经典模式和集成模式两种,具体请看参考。
 
总结                                
  本篇是参考了各位大哥的整理、总结后个人的一个归纳总结,以后继续完善!!
   转载请标明出处哦!http://www.cnblogs.com/fsjohnhuang/archive/2012/07/12/2587658.html
时间: 2024-10-22 19:34:08

Asp.net管道模型(管线模型)之一发不可收拾的相关文章

《圣殿祭司的ASP.NET4.0专家技术手册》----1-12 ASP.NET程序的编译模型

1-12 ASP.NET程序的编译模型 圣殿祭司的ASP.NET4.0专家技术手册 ASP.NET 4.0支持两种编译模型:动态编译(Dynamic Compilation)与预编译(Precompilation),让你来决定不同网站何时该用何种编译模型,不但灵活性提升,且若采用预编译网站,执行性能还可以更高. 1-12-1 ASP.NET网站动态编译 动态编译是用户第一次浏览网站时,ASP.NET会将网站程序编译成一个dll组件文件,后续的请求就会以此组件来响应,而编译过后的网站执行性能明显较

ASP.NET MVC5 网站开发框架模型、数据存储、业务逻辑(三)_实用技巧

前面项目的层次和调用关系都说明了,关系如下图 采用三层架构的时候,研究过BLL层的必要性,觉得业务逻辑完全可以在controller里实现,没有必要单独做一个项目,另一个分层多了会影响性能.后来我还是把业务逻辑独立出来,原因如下: 业务逻辑写进controller里代码看着比较混乱,时间久了代码容易理不清. 在controller里直接写逻辑重复代码会不较多,开发效率低. 分项目有利于代码重用,有时候可以直接拿到其他项目中稍作修改就可以用. 对于性能我觉得分层多了肯定会有影响,但是不会很大.现在

借鉴ASP.NET的控件模型辅助UI自动化测试

概述 在敏捷测试中UI的自动化测试(一般我们也称这层测试为功能测试或验收测试,本文单指Web UI的自动化测试)虽然没有单元测试那么广为提及,但因为其与最终用户最近,所以基于用户场景的UI自动化测试还是有其重要的意义的.使用UI自动化测试对产品的关键功能路径进行验证及回归,比起传统的QA手工执行Test case可以更快地得到反馈,也让发布变得更有信心. 理想状况下,我们应该将所有可以固化下来的Test case都自动化起来,而让我们的测试人员进行更有挑战性的探索性测试活动.让机器做已知领域的事

ASP.NET底层架构探索之ASP.NET管道

asp.net|架构 HttpApplication触发事件来通知你的程序有事发生,以此来负责请求流转.这作为HttpApplication.Init()函数的一部分发生(用Reflector查看System.Web.HttpApplication.InitInternal()方法和HttpApplication.ResumeSteps()方法来了解更多详情),连续设置并启动一系列事件,包括执行所有的处理器(handler).这些事件处理器映射到global.asax中自动生成的哪些事件中,同时

《计算复杂性:现代方法》——第一部分 基本复杂性类 第1章 计算模型——为什么模型选择无关紧要 1.1 计算的建模:你真正需要了解的内容

第一部分 基本复杂性类 第1章 计算模型--为什么模型选择无关紧要 初看起来,为计算建立数学模型可谓难上加难.这是由于,历史上人类在解决各种计算任务的过程中用尽了各种各样的方法--从直觉和灵感到算盘或计算尺,再到现代的计算机.此外,自然界中其他生物或系统也时刻需要处理各种计算任务,而它们的解决之道也是纷乱繁杂.怎样才能找出一个能抓住这些计算方法共性的简洁的数学模型呢?如果再考虑到本书要关注的计算效率问题,则建模问题就更加无从下手了.考虑计算效率问题似乎必须小心地选择计算模型,因为即便是孩童也知道

艾伟_转载:[原创]再谈IIS与ASP.NET管道

在2007年9月份,我曾经写了三篇详细介绍IIS架构和ASP.NET运行时管道的文章,深入介绍了IIS 5.x与IIS 6.0HTTP请求的监听与分发机制,以及ASP.NET运行时管道对HTTP请求的处理流程: [原创]ASP.NET Process Model之一:IIS 和 ASP.NET ISAPI[原创]ASP.NET Process Model之二:ASP.NET Http Runtime Pipeline - Part I[原创]ASP.NET Process Model之二:ASP

艾伟:[原创]再谈IIS与ASP.NET管道

在2007年9月份,我曾经写了三篇详细介绍IIS架构和ASP.NET运行时管道的文章,深入介绍了IIS 5.x与IIS 6.0HTTP请求的监听与分发机制,以及ASP.NET运行时管道对HTTP请求的处理流程: [原创]ASP.NET Process Model之一:IIS 和 ASP.NET ISAPI[原创]ASP.NET Process Model之二:ASP.NET Http Runtime Pipeline - Part I[原创]ASP.NET Process Model之二:ASP

[原创]再谈IIS与ASP.NET管道

在2007年9月份,我曾经写了三篇详细介绍IIS架构和ASP.NET运行时管道的文章,深入介绍了IIS 5.x与IIS 6.0HTTP请求的监听与分发机制,以及ASP.NET运行时管道对HTTP请求的处理流程: [原创]ASP.NET Process Model之一:IIS 和 ASP.NET ISAPI[原创]ASP.NET Process Model之二:ASP.NET Http Runtime Pipeline - Part I[原创]ASP.NET Process Model之二:ASP

ASP.NET Core MVC/WebAPi 模型绑定探索

前言 相信一直关注我的园友都知道,我写的博文都没有特别枯燥理论性的东西,主要是当每开启一门新的技术之旅时,刚开始就直接去看底层实现原理,第一会感觉索然无味,第二也不明白到底为何要这样做,所以只有当你用到了,你再去看理论性的文章时才会豁然开朗,这是我一直以来学习技术的方法.本文我们来讲解.NET Core中的模型绑定. 话题 在ASP.NET Core之前MVC和Web APi被分开,也就说其请求管道是独立的,而在ASP.NET Core中,WebAPi和MVC的请求管道被合并在一起,当我们建立控