标签:iis
我曾在(发布网站 IIS部署网站)一文中说到我们看到应用程序池里面有多个(5个)与各个网站同名的应用程序池,为什么每个网站都要有自己的应用程序池呢? 因为分多个应用程序池,后台就有多个进程,处理不同的网站使用单独的进程,各个网站之间就不会相互影响,即便某个网站流量过大,蹦了,瘫痪了,都不会影响其他的网站的正常运行)
IIS里默认的网站名可能与它的应用程序池名不一样,这个我们不管,但是只要是我们自己在IIS上建立的网站,它的网站名称与应用程序池的名称一般都是是同名的。
当我们访问IIS上的一个网站的时候,比如例如我们在这里访问MyTestWebSite这个网站,我们会发现windows任务管理器里多了一个w3wp.exe的进程,用户名是MyTestWebSite 。这个进程就是这个应用程序池里面的进程,帮我们处理对于这个网站的所有请求访问。说白了,这个应用程序池就是支撑这个网站的后台核心进程。
当我们在浏览器一下那个默认的网站Default Web Site 又会发现windows任务管理器又多了一个w3wp.exe的进程,用户名是:DefaultAppPool
假如IIS上部署了10个网站,我访问了这个10个网站,windows任务管理器中就会有10个w3wp.exe的进程,如果我很长时间不访问其中的几个了,那么因之前访问这几个网站而启动的w3wp.exe就会自动销毁。如果你再访问的话,它有会自动启动(记住每一个网站都会有对应的一个应用程序池,每一个应用程序池在处理你对这个网站的请求的时候都会启动一个w3wp.exe的进程)
有这么一句话:一个应用程序池对于的就是一个w3wp.exe进程? 这句话是不对的。答案是:不一定,一个应用程序启动以后池至少有一个w3wp.exe进程,但是我们也在这个应用程序池里也可以设置多个进程(即:在应用程序池->右键->高级设置->进程模型>最大工作进程数。默认是1,我们也可以将它设置成多个)
现在我们就正式来看看浏览器请求一个网站,IIS是如何工作的。
当浏览器向服务器发送一个请求,首先浏览器是根据用户输入的URL地址来封装一个http请求报文,然后通过Socket发送到服务器
,在服务器端 有一个运行在windows内核模式下的http.sys核心组件,这个核心组件是可以监听任何浏览器对服务器80端口的请求
【
注:windows把cpu运行的时候分成2中模式,一种是内核模式,另外一种是用户模式。
用户模式:我们一般运行的应用程序是在用户模式下运行的,用户模式下,当你启动一个应用程序以后,它会给你启动对应的进程,然后会给这个进程分配对应的地址空间来运行我们的程序,这样即便我们的应用程序崩溃了也不会影响其他的应用程序的正常运行。
内核模式:windows操作系统核心的组件是在内核模式下运行的,所有的内核模式下运行的代码是共享单个虚拟地址空间的(即:共享一个地址空间的)所以内核模式下的代码一旦奔溃,操作系统就崩溃了,而用户模式下的某个应用程序崩溃并不会影响操作系统的正常运行。
windows操作CPU 会自动切换内核模式和用户模式来执行程序
】
http.sys这个运行在内核模式的核心组件监听到浏览器的请求以后,并不是由它来处理浏览器的请求,它首先会读取系统的注册表,然后从注册表中查询当前哪个程序可以处理对80端口的http请求,如果系统中安装了IIS,它就会监测到注册表里IIS这个程序(进程)可以对这个80端口的http请求进行处理(如果没有安装,这个http.sys核心组件发现没有可以处理对这个80端口的请求的应用程序,,http.sysy就不不理会了,所以就也不会有响应了) 因为inetinfo.exe是IIS后台服务的核心进程,所以http.sys会把请求交给inetinfo.exe这个进程去处理。
IIS接收到浏览器对这个80端口请求以后,会启动一个叫w3wp.exe的进程(因为w3wp.exe是浏览器请求的网站的应用程序池里面的进程,而IIS开始处理请求的时候又会启动一个w3wp.exe进程,所以我猜测IIS是根据浏览器请求url的端口号来确定到底是启动哪个网站对应的应用程序池里的w3wp.exe进程),然后会查找IIS自己的配置信息,根据请求报文的URL后缀名来判断浏览器请求的是什么类型的资源(静态资源或动态资源),如果是静态资源,w3wp.exe会根据URL路径去读取磁盘上的静态资源,然后把读取到的结果返回给inetinfo.exe(即:IIS),然后IIS又把结果返回给http.sys这个内核模块的核心组件,由它来将结果返回给浏览器。
如果用户请求的是动态资源,它会在启动w3wp.exe这个进程之前 去处理程序映射找到aspx,ashx等.net动态网页应该使用哪个组件来处理,于是它会找到aspnet_isapi.dll这个组件并调用aspnet_isapi.dll这个组件来处理(注:aspnet_isapi.dll是一个C++写的文件,不是.net程序集,所以这个aspnet_isapi.dll会在寄宿在w3wp.exe这个进程中开始执行。
那这个aspnet_isapi.dll是如何执行的呢?
第一步:aspnet_isapi.dll开始启动.net运行时(即:启动.net runtime, 启动.net运行时后会执行这么几个方法:1>获取一个实现了IISAPIRuntime接口类型的对象,这个类型就是ISAPIRuntime,然后调用该对象的ProcessRequest(ecb)方法,这个参数ecb其实就是HTTP的请求报文 ,在ProcessRquest(ecb)这个方法中对浏览器的请求报文做了简单的封装,把请求报文数据封装成了一个ISAPIWorkerProcess类型的对象(假如这个对象名字叫wr),注意:这个封装是及其简单的,不像HttpContext那么详细。 2>开始调用HttpRuntime.ProcessRquestNoDemand(wr)方法, 然后在这个方法中对wr这个对象又进行了详细的封装,封装成了HttpContext对象(注:HttpContext对象里面有HttpRequest类型的属性Request,和HttpResponse类型的属性Response)。 3>通过工厂模式创建一个HttpApplication对象,创建完该对象后悔调用该对象的一系列方法对浏览器的请求做处理(其中肯定会调用一个方法,这个方法就是ProcessRequest(context) 方法),处理用户的请求就会触发19个事件,23步。等都处理完后,就将处理的结果返回给inetinfo.exe ,然后由inetinfo.exe将结果返回给http.sys,然后http.sys将结果通过socket返回给浏览器)
)
(通过配置IIS中的处理程序映射,来决定不同的后缀名使用什么样的方式来处理来处理,比如请求的URL后缀名是.aspx 就调用aspnet_isapi.dll这个组件来处理)
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:iis
原文地址:http://blog.csdn.net/fanbin168/article/details/47679847