之前在网上看过很多对这方面的讲解,但个人觉得看下来过于 "深奥",不容易理解,所以想用更简单的方式进行阐述,便于理解。
本次我们重点分析用户请求到页面呈现过程中Web服务器的处理过程。我们从ASP.NET站点的一个页面请求开始说起,先看下面对于某个请求的简单执行模型
(注意这是对asp.net站点Index.aspx页面的第一次请求,所以需要进行动态编译):
我们通过ASP.NET的执行模型简单的描述了一次web请求过程,注意在不同的IIS版本中,处理模型和通信方式是不一样的,在IIS7.0以上asp.net已经作为一个模块集成在了IIS中。
我们继续对上面的流程进行相关阐述:
- 首先我们通过浏览器发送页面请求至IIS服务器,由于是第一次请求index.aspx,IIS会将请求转交给ASP.NET后进入编译期(加载aspnet_isapi.dll)
- 由于ASP.NET是通过CLR运行,而CLR只认识MSIL(微软中间语言),所以ASP.NET会判断代码是否已被编译,若未被编译则会走二次编译流程,否则跳过编译进入执行期,
- 在执行期进行一系列的模块处理,然后返回请求
接着我们来看看什么是二次编译?
二次编译:
将源代码文件通过编译器编译成中间语言代码和元数据,执行时再编译为本地机器语言代码的过程。
感觉不好理解?那就直接看图吧!
如上,我们把这两次编译的过程叫做二次编译。
二次编译在站点页面首次被请求时执行,ASP.NET判断已经编译过的不会再走编译流程。
看完二次编译然后我们再对asp.net站点Index.aspx进行首次请求:
用户请求—>IIS服务器—>ASP.NET—>二次编译—>MSIL(代码编译器)—>本机语言(JIT)—>执行期
- 创建应用程序域
- 初始化核心对象
- 启动应用程序
- 根据配置对请求进行处理,一系列HTTPModule和HTTPHandler
最后请求通过一层层HttpModule和HttpHandler后进入页面的初始化,加载,呈现,用户操作,卸载。
这就解释了为什么我们的站点页面第一次被请求的时候总是慢一点的原因,原因就是第一次请求时走了编译的过程,加载了一系列初始化的东西。
如果我有多个应用程序池多个站点都部署在一台IIS服务器,我发一个请求IIS如何知道我请求的是哪个呢?这里就会提到到一个HTTP.SYS组件。
其实在IIS将请求交给ASP.NET之前,会最先触发HTTP.SYS的响应,由HTTP.SYS负责把请求传入相应的应用程序池。然后继续走上面的ASP.NET流程
每当创建一个应用程序池,该池的ID就会生成并在HTTP.SYS文件中注册。
总结:
如上图:在执行期会进行一系列的操作,然后通过HttpModule模块到达HttpHandler处理程序,最后开始进入页面的生命周期相关的东西。
看完如果对你有帮助还可关注公众号CodeL获取更多内容。