1. 程式人生 > >如何理解IIS 7的兩種應用程式池的管道模式(Managed Pipeline Mode)

如何理解IIS 7的兩種應用程式池的管道模式(Managed Pipeline Mode)

之前我寫過一篇部落格文章,講的是.NET 4.0的應用程式部署問題。有網友問到一個相關問題就是:如何理解IIS 7中的應用程式池的管道模式,尤其是如何理解“託管模型(integrated mode)”,今天特意再寫一篇文章來介紹這個問題。

IIS 7是微軟最新版本的IIS版本,從Vista開始提供,目前在Vista,Windows 7,Windows Server 2008中提供。這個全新的版本中,一個突出的亮點就是,它提供了兩種管道模式,來支援不同的應用程式場景。

這裡提到的管道模式,指的是應用程式池(Application Pool)的一個屬性

image

上圖中可以看到,這兩種管道模式分別為Integrated(整合)和 Classic(經典)

那麼,到底如何理解這兩種模式呢?

Classic模式:指的是與IIS 6或者之前版本保持相容的一種模式,一個典型問題就是,在處理ASP.NET這種動態網站的時候,它是通過一個所謂的ISAPI程式,作為外掛的方式來工作的。針對不同的動態應用程式(例如ASP,PHP等),會需要不同的ISAPI。

例如,下面就是一個註冊號的ISAPI對映

image

從上圖可以看出,不同的Request,指定了不同的ISAPI程式。下圖是對於這種Pipeline的一個圖形化說明

iis 6 pipelines

Integrated模式:這種全新的模式,允許我們將ASP.NET更好地與IIS整合,甚至允許我們在ASP.NET中編寫一些功能(例如Module)來改變IIS的行為(擴充套件)。整合的好處是,不再通過ISAPI的方式,提高了速度和穩定性。至於擴充套件,則可以使得我們對於IIS,以及其他型別的請求有更多的控制。(例如,我們希望靜態網頁也具備一些特殊的行為)

下圖解釋了這一點。

iis 7 integrated mode

以上兩個圖片來自與下面這個文章,並且該文章有更詳細的一些理論介紹。

下面,我就通過一個例子,來幫助大家更好地瞭解整合模型。

這個例子裡面,我有一個特殊的需求就是,我希望對網站裡面所有請求做一個日誌監控,不管是動態網頁,還是靜態網頁。

1. 建立一個Web Application

image

2. 新增一個HttpModule

為了對使用者請求進行監控,我們一般會編寫一個HttpModule

image

image

我為該模組實現簡單的功能(將使用者的請求地址打印出來在頁面上)

using System;
using System.Web;

namespace WebApplication2
{
    public
class MyModule1 : IHttpModule { /// /// You will need to configure this module in the web.config file of your /// web and register it with IIS before being able to use it. For more information /// see the following link: http://go.microsoft.com/?linkid=8101007 /// #region IHttpModule Members public void Dispose() { //clean-up code here. } public void Init(HttpApplication context) { // Below is an example of how you can handle LogRequest event and provide // custom logging implementation for it context.LogRequest += new EventHandler(OnLogRequest); } #endregion public void OnLogRequest(Object source, EventArgs e) { //custom logging logic can go here var app = (HttpApplication)source; app.Response.Write(app.Request.Url.ToString()); } } }

3.註冊該模組

模組是需要註冊才能夠使用的。我們一般會想到以前的做法

  <system.web>
    <compilation debug="true" targetFramework="4.0" />
    <httpModules>
      <add name="test" type="WebApplication2.MyModule1,WebApplication2"/>
    httpModules>
  system.web>

但這樣註冊,會遇到一個錯誤

image

這個錯誤的意思是,LogRequest這個操作,是必須執行在整合模式下的。

那麼,到底如何註冊成整合模式的模組呢?

我們需要將配置檔案修改成下面這樣

<?xml version="1.0"?>



<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
    
  system.web>

  <system.webServer>
    <modules>
      <add name="test" type="WebApplication2.MyModule1,WebApplication2"/>
    modules>
  system.webServer>

configuration>

請注意,現在多了一個system.webServer的節,裡面有一個modules的節,可以配置需要註冊的一些HttpModule

因為是註冊為system.webServer的Module,所以,在visual studio中除錯是沒有效果的

image

我們需要將該應用程式釋出到IIS,並且設定為integrated mode。

4.釋出到IIS

有很多辦法進行釋出,我所推薦的是用deploy package的方式。

image

請注意,我們使用的Application Pool是integrated mode的

image

釋出之後,我們在瀏覽器中瀏覽首頁,我們會發現在底部會有一個特殊的輸出,就是我們當前請求的地址資訊。這說明,我們那個Module已經在工作了。

image

5.測試該模組對於靜態頁面的支援

如果僅僅是上面這樣,我們似乎看不出這種模式到底有何優勢。我們以前不也是可以實現這樣的效果嗎?

請你主要的是,以前的HttpModule只能影響到動態網頁,例如我們的ASPX網頁,而對於靜態網頁(例如html),或者其他型別的動態網頁(例如php等)是無能為力的。

那麼,現在這種模式下情況是怎樣的呢?

我們可以新增一個簡單的html頁面,放在網站根目錄下

image

然後,我們去請求該頁面

image

是不是很神奇呢?雖然是靜態網頁,但因為我們那個模組是註冊在IIS裡面的,它改變了IIS的行為,所以仍然會在頁面底部插入一段輸出。

6.總結

希望上面這樣的例子可以幫助大家更好地理解Integrated mode。它是允許我們將程式碼插入到IIS核心中,而不再通過ISAPI的方式。這將帶來更好的效能和擴充套件性。