IIS 8.0 應用程式初始化

作者 :Shaun Eagan

相容性

版本 備註
IIS 8.0 應用程式初始化是 IIS 8.0 的內建專案。
IIS 7.5 應用程式初始化已發行為 IIS 7.5 的頻外模組
IIS 7.0 IIS 7.0 不支援應用程式初始化。

問題

網站管理員所面臨的常見問題是需要執行 Web 應用程式的初始化工作和「準備」工作。 較大型且更複雜的 Web 應用程式可能需要執行冗長的啟動處理、記憶體內部快取、產生內容等等...在提供第一個 HTTP 要求之前。

解決方案

IIS 8.0 應用程式初始化功能可讓網站系統管理員設定 IIS 8.0,以主動執行一或多個 Web 應用程式的初始化工作。 當應用程式初始化時,IIS 8.0 也可以設定為將靜態內容當做佔位元或「啟動顯示頁面」傳回,直到應用程式完成初始化工作為止。

應用程式初始化功能是透過全域和應用程式特定規則的組合來設定,告知 IIS 8.0 如何及何時初始化 Web 應用程式。 應用程式初始化功能也支援與 IIS URL 重寫模組整合,以支援在應用程式仍在初始化時更複雜的佔位元元內容處理。

注意

應用程式初始化和應用程式要求路由 (ARR) 之間已知不相容。 不建議在已安裝ARR的機器上使用應用程式初始化。

逐步指示

必要條件

應用程式初始化功能需要安裝 IIS 8.0。 此外,必須安裝 IIS「應用程式開發」子功能內的應用程式初始化功能。

下列來自 Windows Server 2012 伺服器管理員 UI 的螢幕快照顯示應用程式初始化功能。

此螢幕快照顯示安裝在 Windows Server 2012 上的應用程式初始化功能。

注意

本逐步解說也會使用 ASP.NET 4.5 應用程式來示範應用程式初始化功能。 本檔結尾的附錄包含範例應用程式,以及在計算機上設定應用程式的指示。

已知 Bug 的因應措施

  • 這項功能目前沒有已知的 Bug。

全域應用程式初始化

應用程式初始化功能可以在兩個位置進行設定:全計算機 applicationHost.config 檔案,以及應用層級 web.config 檔案。 applicationHost.config 檔案中的組態包含「全域」應用程式初始化設定,而應用層級 web.config 檔案則包含「本機」應用程式初始化設定。

在本逐步解說中,您會在應用程式相關聯的應用程式集區啟動時,將範例應用程式設定為一律初始化。 由於應用程式集區行為只能在 applicationHost.config 中設定,每當應用程式集區啟動時,執行應用程式初始化會被視為「全域」應用程式初始化設定的一部分。

applicationHost.config 中的修改

開啟位於 [記事本] 中的 applicationHost.config 檔案 %WINDIR%\system32\inetsrv\config 。 (記得使用 [以系統管理員身分執行] 選項執行文本編輯器!)

尋找 applicationPools> 組<態區段,然後尋找名稱為 “.NET v4.5” 的應用程式集區專案。

修改應用程式集區專案,讓應用程式集區一律執行。 針對您想要進行全域應用程式初始化的應用程式,您通常會想要啟動和執行相關聯的應用程式集區。 組態代碼段中的粗體屬性會顯示要新增至組態項目的內容。

<add name=".NET v4.5" startMode="AlwaysRunning" managedRuntimeVersion="v4.0" />

向下捲動 applicationHost.config 至 <sites> 組態專案。 在該區段中, <application> 範例應用程式 (請參閱附錄,以取得在機器上建立範例應用程式的指示) 。 應用程式稱為 「appinit」 且路徑屬性值為 「/appinit」。 <application>藉由新增粗體預先loadEnabled 屬性來修改專案,如組態代碼段中所示,然後儲存您的變更。

<application path="/appinit" preloadEnabled="true" applicationPool=".NET v4.5">

preloadEnabled 設定為 「true」 會告訴 IIS 8.0,當相關聯的應用程式集區啟動時,它會將「假」要求傳送給應用程式。 這就是為什麼在上一個步驟中,我們將應用程式集區的 startMode 設定為 “AlwaysRunning”。

當計算機重新啟動和/或 World Wide Web 服務回收時,應用程式集區一律會執行,且標示為一律會收到假要求的應用程式本身時,IIS 8.0 可確保應用程式集區實例正在執行,而且應用程式 “/appinit” 一律會傳送假要求來觸發應用程式啟動。

應用程式 web.config 中的修改

使用記事本的第二個實例,開啟位於下列位置的應用程式層級 web.config 檔案。 (記得使用 [以系統管理員身分執行] 選項執行文本編輯器!)

C:\inetpub\wwwroot\appinit

注意:如果您的默認網站安裝在不同的實體磁碟驅動器上,請變更驅動器號。

web.config 檔案已預先填入幾個組態區段,但已批注化。取消批註顯示於組態區段內的 <system.webServer> 組態代碼段。 此代碼段位於 web.config 檔案中的批注 「練習 1 - 步驟 1」下方。 然後儲存您的變更。

<applicationInitialization
    remapManagedRequestsTo="Startup.htm" 
    skipManagedModules="true" >
  <add initializationPage="/default.aspx" />
</applicationInitialization>

applicationInitialization 元素會告訴 IIS,它應該發出要求給應用程式的根 URL (“/default.aspx”,在此範例中) 以初始化應用程式。 雖然 IIS 會等候要求 「/default.aspx 完成,但它會將 」Startup.htm」 提供給任何作用中的瀏覽器用戶端。 “Startup.htm”是應用程式的「啟動顯示頁面」。

執行應用程式

提升權限的 命令提示字元視窗中,使用如下所示的命令回收 World Wide Web 服務:

net stop w3svc & net start w3svc

請記得使用 [以系統管理員身分執行] 選項執行命令提示字元視窗!

使用 Internet Explorer,流覽至下列 URL:

http://localhost/appinit/default.aspx

瀏覽器會在前幾秒傳回具有灰色背景的靜態 「Startup.htm」頁面,因為這是 web.config 中設定的「啟動顯示頁面」。您可以繼續在網頁瀏覽器中重新整理頁面,並觀察在範例應用程式的 global.asax 中模擬線程睡眠 (大約 8 秒,) 您收到具有白色背景之 default.aspx 的「實際」內容。 這表示應用程式初始化已完成。

設定重疊的進程回收

IIS 8.0 藉由在背景的重疊進程中執行應用程式初始化,將全域應用程式初始化與重疊的進程回收整合。 當 IIS 偵測到作用中背景工作進程正在回收時,IIS 不會將作用中的流量切換至新的回收背景工作進程,直到新的背景工作進程完成在新進程中執行所有應用程式初始化 URL 為止。 這可確保在應用程式上線並執行後,瀏覽您的網站的客戶不會看到應用程式初始化頁面。

返回 具有 applicationHost.config 的記事本實例。修改 「.NET v4.5」 的應用程式集區專案,看起來像下面所示的組態代碼段:

<add name=".NET v4.5"
                startMode="AlwaysRunning"
    managedRuntimeVersion="v4.0" >
  <recycling logEventOnRecycle="Schedule">
    <periodicRestart requests="30" />
  </recycling>
</add>

請記得儲存您的變更!

<回收>專案會告訴 IIS 每隔 30 個 HTTP 要求回收背景工作進程。

第二次執行應用程式

提升權限的 命令提示字元視窗中,使用如下所示的命令回收 World Wide Web 服務:

net stop w3svc & net start w3svc

使用 Internet Explorer 的新實例,再次流覽至:

http://localhost/appinit/default.aspx

請注意,顯示灰色背景的 「Startup.htm」啟動顯示頁面。

接下來,提取任務管理員,並確定 [ 行程 ] 索引標籤已顯示。 依名稱排序進程清單,直到您看到執行中的一個實例 w3wp.exe 為止。 該實例是目前正在執行 「appinit」 ASP.NET 應用程式的背景工作進程。

顯示執行 w 3 w p 可執行檔之一實例之 Task Manager 行程清單的螢幕快照。

重新整理瀏覽器幾次,直到傳回實際 default.aspx 頁面的內容為止。 您知道當背景變更為白色時,應用程式正在執行 「real」 default.aspx 頁面。 接下來,排列畫面上的視窗,讓您可以查看任務管理員和瀏覽器。

現在切換回瀏覽器並至少重新整理頁面 30 次,這會導致 IIS 回收應用程式集區。 當您看到第二個實例 w3wp.exe 顯示在任務管理器進程清單中時,您可以停止重新整理頁面,如下所示:

此螢幕快照顯示任務管理器進程清單中 w 3 w p 可執行檔的第二個實例。

此螢幕快照顯示因為稍早設定的進程回收限制而啟動 w3wp.exe 的第二個實例。

您可以繼續在接下來的十秒內定期重新整理瀏覽器視窗。 請注意,default.aspx 會繼續執行。 當重迭回收完成時,一個 w3wp.exe 實例會從 [任務管理器進程] 視窗消失。

在重疊回收的期間,即使您已針對應用程式設定應用程式初始化,且已在 w3wp.exe 的新實例背景中執行初始化 URL,您仍會繼續看到“real” default.aspx 提供的內容。

URL 重寫和應用程式初始化

根據預設,應用程式初始化只會讓您指定單一「啟動顯示頁面」URL,以在應用程式初始化時顯示。 不過,應用程式初始化功能支援一些伺服器變數,可用來控制應用程式初始化時的要求處理。 這可讓您使用 URL 重寫模組來建立宣告式規則,其中包含預先產生的靜態內容更複雜的對應。

在本逐步解說中,您會將 remapManagedRequestsTo 屬性取代為一組可完成相同結束結果的 Url 重寫規則。

注意:如需安裝 URL 重寫的指示,請參閱附錄。

applicationHost.config 中的修改

使用已開啟 applicationHost.config 記事本的實例,還原應用程式集區和應用程式元素,以關閉所有全域應用程式初始化處理。 此步驟中會移除全域設定,因為本逐步解說的其餘部分著重於已設定的應用程式初始化行為。

應用程式集區和應用程式的 applicationHost.config 專案如下所示。

應用程式集區組態專案:

<add name=".NET v4.5" managedRuntimeVersion="v4.0" />

應用程式組態專案:

<application path="/appinit" applicationPool=".NET v4.5">

請記得在完成時儲存您的變更!

此外,若要確保變更在 IIS 中生效,請從 提升許可權 的命令提示字元視窗中,使用如下所示的命令回收 World Wide Web 服務:

net stop w3svc & net start w3svc

對應用層級 web.config 的修改

使用已開啟應用層級 web.config 的記事本實例,從 <applicationInitialization> 元素中移除 remapManagedRequestsTo 屬性。 組 <applicationInitialization> 態區段現在看起來應該像這個組態代碼段。

<applicationInitialization skipManagedModules="true" >
  <add initializationPage="/default.aspx" />
</applicationInitialization>

因為 專案 <applicationInitialization> 不再定義要重新對應要求的 URL,所以請新增一組 URL 重寫規則。 接下來,新增重寫規則,明確地將提出的要求對應至 「default.aspx」,以及 「以路由傳送至 」Startup.htm」。 需要兩個規則,因為 URL 重寫模組無法「知道」預設文件的運作方式。 由於 「/」 相當於 ASP.NET 應用程式中的 「default.aspx」,因此您需要兩個 URL 重寫規則 -每個 URL 變化都有一個規則。

新的規則如下所示,以粗體顯示。 或者,您可以在 web.config 檔案中的「練習 2 - 步驟 2 - 將要求對應至首頁」批注下,取消批注預先填入的 Url 重寫規則。

<rewrite> 
  <rules>
    <rule name="Home Page-Expanded" stopProcessing="true">
      <match url="default.aspx" />
      <conditions>
        <add input="{APP_WARMING_UP}" pattern="1" />
      </conditions>
      <action type="Rewrite" url="Startup.htm" />
    </rule>
    <rule name="Home Page-Short" stopProcessing="true">
      <match url="^$" />
      <conditions>
        <add input="{APP_WARMING_UP}" pattern="1" />
      </conditions>
      <action type="Rewrite" url="Startup.htm" />
    </rule>
  </rules>
</rewrite>

要記下這些規則的某些專案:首先,stopProcessing 屬性會在規則 /> 元素上<設定為 “true”。 這是稍後新增 catch-all Url Rewrite 規則的必要條件,以及您不想執行 catch-all 規則的 default.aspx 或 “/” 要求。

其次,請注意,我們在條件 /> 元素中有 <URL 重寫條件。 此條件實際上表示「只有在應用程式處於初始化狀態時才套用規則」。 當應用程式初始化為使用中且 IIS 仍在處理所有初始化 URL 時,伺服器變數 「APP_WARMING_UP」 會設定為 「1」。

最後,請注意,動作已定義為重寫使用中要求,改為執行 「Startup.htm」。。 此規則的效果是告訴 IIS 將要求傳遞至靜態檔案處理程式,然後轉譯靜態頁面 Startup.htm。

接下來,您會新增 catch-all 重寫規則。 搭配應用程式初始化使用 Url 重寫模組時,如果不需要任何先前的規則相符專案,就會引發攔截式規則。 將如下所示的粗體規則新增至重寫區段作為 catch-all 規則。 或者,您可以在位於 web.config 檔案中「練習 2 - 步驟 2 - 步驟 2 設定 Catch-All 規則」批註底下的 web.config 取消批注預先填入的 catch-all 規則。

<rewrite> 
  <rules>
    <rule name="Home Page-Expanded" stopProcessing="true">
      <match url="default.aspx" />
      <conditions>
        <add input="{APP_WARMING_UP}" pattern="1" />
      </conditions>
      <action type="Rewrite" url="Startup.htm" />
    </rule>
    <rule name="Home Page-Short" stopProcessing="true">
      <match url="^$" />
      <conditions>
        <add input="{APP_WARMING_UP}" pattern="1" />
      </conditions>
      <action type="Rewrite" url="Startup.htm" />
    </rule>
    <rule name="All Other Requests">
      <match url=".*" />
      <conditions>
        <add input="{APP_WARMING_UP}" pattern="1" />
      </conditions>
      <serverVariables>
        <set name="SKIP_MANAGED_MODULES" value="0" />
      </serverVariables>
      <action type="Rewrite" url="{URL}" />
    </rule>
  </rules>
</rewrite>

完成時儲存您的變更!

新的規則會比對到達它的任何 URL,並告知 IIS 繼續處理對輸入 URL 提出的要求。 此規則也會將名為 「SKIP_MANAGED_MODULES」 的伺服器變數設定為 「0」 的值,這相當於 「false」。 此設定會告訴 IIS,它應該以與要求正常抵達網路的方式相同,處理來自 Url 重寫的重寫要求。

執行應用程式

從提升權限的命令提示字元視窗中,使用如下所示的命令回收 World Wide Web 服務:

net stop w3svc & net start w3svc

使用 Internet Explorer 的新實例,再次流覽至:

http://localhost/appinit/default.aspx

即使 URL 重寫規則現在用來定義啟動顯示頁面邏輯,您仍會看到第一個逐步解說中的相同行為。 一開始會顯示具有灰色背景的 Startup.htm 頁面。 如果您定期重新整理瀏覽器,稍後大約 8 秒就會再次看到頁面背景切換為白色,表示現在已提供「實際」default.aspx 頁面,應用程式初始化已完成。

複雜的啟動顯示頁面規則

上述逐步解說會使用應用程式初始化作為 URL “X” 與 Url “Y” 的直接對應。 在本逐步解說中,您將實作更複雜的應用程式初始化案例。

在您的瀏覽器中,瀏覽至下列兩個URL:

  • http://localhost/appinit/ImageHandler.ashx?image=Lighthouse
  • http://localhost/appinit/ImageHandler.ashx?image=Tulips

這些 URL 是動態產生的靜態內容的範例。 在此範例應用程式中,ImageHandler.ashx 內的程式代碼會查看查詢字串索引鍵 「image」。 如果該查詢字串的值是 「Lighthouse」 或 「Tulips」,則 ASP.NET 處理程式會傳送位於 App_Data 資料夾中的對應 JPG。

由於映像處理程式只是傳回影像,因此即使應用程式初始化期間,您仍可繼續傳回適當的映像。 雖然提供這些映像的機制使用 Managed 程式代碼,但即使基礎 ASP.NET 應用程式需要很長的時間來啟動並初始化本身,您仍可能會想要快速提供給客戶預先產生的映像。

對應用層級 web.config 的修改

使用已開啟應用層級 web.config 的 [記事本] 實例,在最後一個 catch-all 規則 之前 新增另一個 URL 重寫規則。 要新增的新代碼段如下所示。 或者,您可以在位於 web.config 檔案中的「練習 3 - 步驟 1 複雜啟動顯示頁面規則」批註底下,取消批註 web.config 中預先填入的影像處理程序規則。

<rule name="Image Handler Remapping" stopProcessing="true">
  <match url="ImageHandler.ashx" />
  <conditions>
    <add input="{APP_WARMING_UP}" pattern="1" /> 
    <add input="{QUERY_STRING}" pattern="image=([A-Za-z]+)&amp;?" /> 
  </conditions>
  <action type="Rewrite" url="Images/{C:1}_static.jpg" appendQueryString="false" />
</rule>

完成時儲存您的變更。

如同 default.aspx 和 “/” 的重寫規則一樣,此規則的 stopProcessing 屬性會設定為 “true”,以確保在應用程式初始化期間,對 ImageHandler.ashx 的要求不會意外落入至最終的 catch-all 重寫規則。

對於 「ImageHandler.ashx」 的要求,重寫規則會使用正則表達式擷取群組,從查詢字串擷取要求的影像。 比對模式定義 模式=“image= ([A-Za-z]+) &?” 指示 IIS 擷取 「image」 查詢字串變數的值。 該值接著會用於動作屬性的 url 屬性:url=“Images/{C:1}_static.jpg”。

action 元素上的 url 屬性會告訴 Url Rewrite 模組重寫 ImageHandler.ashx 要求,改為指向應用程式的 Images 子目錄中的檔案。 此外,正則表達式所擷取的查詢字串值可用來協助形成最終會從Images 子目錄提供之檔名。 例如, ImageHandler.ashx?image=Tulips 的要求會重寫為 Images/Tulips_static.jpg

如果您使用 Windows 檔案總管流覽至 inetpub\wwwroot\appinit 目錄,並查看 Images 子目錄,您會看到兩個檔案:一個代表 Tulips.jpg 的「靜態」版本,另一個則代表 Lighthouse.jpg 的「靜態」版本。 這些靜態影像可作為預先產生的內容,可在應用程式初始化時提供。

執行應用程式

從提升權限的命令提示字元視窗中,使用如下所示的命令回收 World Wide Web 服務:

net stop w3svc & net start w3svc

使用 Internet Explorer 瀏覽至下列其中一項:

http://localhost/appinit/ImageHandler.ashx?image=Lighthouse

http://localhost/appinit/ImageHandler.ashx?image=Tulips

請注意,兩種情況下傳回的影像如何包含浮浮浮浮水印,指出這些是映射的「靜態」預先產生版本。 浮浮浮水印是影像上方部分的文字,指出「此影像是 的靜態版本...」。

如果您在稍後大約 10 秒重新整理瀏覽器,您會看到傳回的影像內容變更為 ImageHandler.ashx 處理程式所提供的「實際」內容。 浮水印消失,表示內容現在由 ASP.NET 處理程式動態產生,因為應用程式已完成初始化。

[注意:如果 Internet Explorer 似乎未重新整理,請按兩下網址列中的「中斷的檔」圖示或重新整理圖示,強制 Internet Explorer 重載頁面。]

摘要

IIS 8.0 應用程式初始化功能可讓開發人員和系統管理員在 IIS 初始化「冷」應用程式時,將靜態內容傳回瀏覽器。 立即將靜態內容提供給瀏覽器,可讓客戶獲得更好的用戶體驗。 除了產生空白瀏覽器頁面或旋轉等候圖示的冷啟動應用程式,也可以使用應用程式初始化功能來提供相關的靜態內容,而基礎應用程式完成昂貴的初始化處理。

每當網頁伺服器上線或回收時,就會自動進行初始化程式。 對於伺服器管理員不想要窮盡初始化應用程式的案例,當第一個要求抵達「冷」應用程式時,可以改為隨選觸發初始化程式。

針對全域和本機應用程式初始化,URL 重寫模組可以整合以提供更豐富且更複雜的初始化規則。 使用與應用程式初始化功能整合的 Url 重寫規則,可以針對不同的 URL 和虛擬路徑提供不同類型的預先產生靜態內容,而 IIS 會繼續在背景中啟動應用程式。

附錄 - 設定範例 ASP.NET 應用程式

注意 - 下列步驟假設您的伺服器 已安裝 IIS 8.0,並啟用 ASP.NET 4.5,以用於 IIS 8.0。

將範例應用程式解壓縮

範例 ASP.NET 應用程式包含在下列 .zip 檔案中:

將檔案解壓縮到網頁伺服器上的 wwwroot 資料夾。 例如,如果您的網頁伺服器已在 C:\ 磁碟驅動器上安裝「預設網站」,請將檔案的內容解壓縮至 c:\inetpub\wwwroot\appinit

在 IIS 8.0 中建立應用程式

將 「appinit」 範例解壓縮到檔案系統之後,您必須在 IIS 8.0 中將資料夾設定為 ASP.NET 應用程式。 下列螢幕快照顯示在 IIS 8.0 中設定為應用程式的 appinit 範例應用程式。 另請注意,應用程式會指派給 “.NET v4.5” 應用程式集區。

I S 管理員的 [進階設定] 功能表螢幕快照。範例應用程式與應用程式集區會反白顯示。

安裝 URL 重寫模組

範例應用程式會使用 Url 重寫模組,進階整合應用程式初始化功能。 您必須在伺服器上安裝 URL 重寫模組;您可以從下載它: https://www.iis.net/downloads/microsoft/url-rewrite

設定 URL 重寫模組

在網頁伺服器上安裝 URL 重寫模組之後,您必須修改 IIS applicationHost.config 檔案,以允許使用應用程式初始化功能所支援之SKIP_MANAGED_MODULES伺服器變數。

在文本編輯器中開啟全計算機 applicationHost.config 檔案,例如記事本。 例如,如果您在 C:\ 磁碟驅動器安裝作業系統,applicationHost.config 檔案位於 C:\Windows\System32\inetsrv\config

向下捲動檔案並找出安全性區段。 本節開頭為 Xml 元素: <安全性>。

在安全性>專案之前<輸入下列 Xml 元素:

<rewrite>
  <allowedServerVariables>
    <add name="SKIP_MANAGED_MODULES" />
  </allowedServerVariables>
</rewrite>

將變更儲存至 applicationHost.config 檔案。