Web 服务器 VS Web 应用程序
在了解 IIS 如何处理 ASP.NET 请求之前,我们必须要清楚 Web 服务和 Web 应用程序之间的界限。Web 服务器与 Web 应用程序之间的关系,就像 操作系统 与 普通桌面应用程序之间的关系一样 —— 一个提供了运行环境,一个提供实际的业务功能实现。简短一点说,一个是宿主 Host ,一个是应用程序 Application。操作系统能够为各种各样的应用程序提供运行环境,而 Web 服务器是构建于操作系统之上的、具有针对性的应用程序宿主(针对 Web 应用程序),就像 Windows 服务一样。没错,如果你对 Windows 服务的了解多过 Web 服务器,那么使用类比法通过 Windows 服务来了解 Web 服务器是个不错的选择(事实上用 Web服务 替代 Web服务器来表述可能会更合理一点,但这样就很容易将 Web服务 与 .NET Web Service 技术搞混)。
IIS(Internet Information Services)
在中文操作系统中,IIS 被称为 互联网信息服务 —— 这是 Microsoft 公司提供的运行于 Windows 操作系统之上的 Web 服务器,它的功能绝不只是能处理 ASP.NET 请求。但本文要尝试讲明的是 IIS 如何处理 ASP.NET 请求,所以,我们可以假设“IIS就是为 ASP.NET 而生的”。
IIS 如何处理 ASP.NET 请求
作为 Web 服务器,IIS 的主要工作是接收请求并通过Web管理服务(Web Admin Services,WAS)将请求分发给不同的应用程序池。
应用程序池接收到请求后,根据当前运行状况将请求投放给某个工作进程(w3wp.exe),工作进程会依据请求 url 的相关特性(比如后缀 aspx)选择和加载特定的 ISAPI(Internet Server Application Programming Interface,网络服务应用编程接口)。
ASP.NET 对应的 ISAPI 为 aspnet_isapi.dll, 它将构造一个 HttpRuntime 作为应用程序入口,从这里开始,请求将会来回经过HttpApplication 中的一序列 HttpModule 和 HttpHandler,然后做出响应。
aspnet_isapi.dll
.NET 程序员应该都知道,想要 ASP.NET 正常运行,必须安装 .NET Framework。但有时候明明已经安装了 .NET Framework,部署在 IIS 上的网站却怎么也不能正常访问,然后在网上折腾捣鼓,终于在运行 aspnet_regiis 并设置应用程序池的 .NET Framework 版本之后就可以正常访问了。 没错,运行 aspnet_regiis 的目的是为了 将相应版本的 .NET Framework 注册到 IIS ,如果你是先安装 IIS ,后装 .NET Framework, 就无需那么复杂 —— .NET Framework 会自动注册。
.NET Framework 注册到 IIS 时,就会给 IIS 添加相应的 ISAPI —— aspnet_isapi.dll。
IIS 如何知道哪个请求该分发给哪个应用程序池
IIS 内核模块(Kernel Mode)包含一个 HTTP.SYS 文件。
向 IIS 添加一个应用程序池的同时会生成一个对应的标识ID,并被记录到 HTTP.SYS(事实上记录的是 url 与 应用程序池之间的对应关系)。
任何来自客户端的 HTTP 请求都将首先触发 HTTP.SYS 。事实上 HTTP.SYS 本身不会执行任何代码,它仅仅是监听客户端的 HTTP 请求。HTTP 请求包含了 Web 站点的主机(或 IP)、端口和资源路径信息,即 url —— 根据映射,IIS 自然就知道如何分发请求给应用程序池了。