上篇提到跟網站設定相關的內容裡,有個重要的選項是 Application Pool (中文是 應用程式集區),也常常提到應用程式層面的安全性隔離會和這個相關,這篇會來介紹一下 Application Pool 在 IIS 中的角色與它的功能。
在網站實際運行的場景裡,Application Pool 會負責處理關於進程(Process)「設定」管理,實際來應用這些設定,起 Process 的服務我們會在下篇提到。
很多時候,網站出錯的原因比起網站設定,更容易因 Application Pool 的設定而發生。從左側欄選擇 Application Pool 就能看到這個畫面 :
其實這個畫面就有一段簡單解釋: application pool 是什麼?它與 worker processes 相關,包含一個或多個 application,並讓不同的 application 間彼此隔離。
如果依照這篇 官方文檔,我們可以來把句子再加長一些 :一個 application pool 定義了一組一或多個 worker process,依照被設定的通常設定來為被指定至此 application pool 的一個或多個 application 服務。
這邊對「隔離」有更完整一點的解釋,它是以進程來做隔離,單一個 application pool 會負責維護一個或多個 Process (多個是有開 Web Garden功能的情況下,Advance Setting介紹會提到),當一個 application pool 出問題了,可能會致使該 application Pool 維護的 Process 出現錯誤。
所以雖然我們可以選擇多個網站用同一個 application pool,可一旦其中一個程式因未預期的錯誤讓 process 出問題,那同一個 application pool 底下的其他網站可能就都會一並出問題。在實際 Production 環境下,應該會想盡量減少風險,就算真的有網站掛了,也要盡量減小範圍,在比較好的 Practice 裡,應該要盡可能地讓一定規模的程式或彼此不相干的程式就各自拆開,使用各自的 Application Pool。
就如同標題寫的小圈圈,圈圈間彼此不互不干擾,各自運行。一個圈圈出問題,影響範圍最多也就那個圈圈的人,對服務的安全與穩定性來說是很重要的概念。
參照官方文檔的時候,其實這段它會持續提到 “worker process” 這個詞,這個詞跟一般的 process 有什麼差異呢,其實在 IIS 裡的 work process 會是特指 w3wp.exe 這個進程,也就是網站程序運行的實體 process。
當網站運行時,你打開工作管理員就能看到它:
所以關於 Application Pool 可以這麼理解,基本上就是基於 Application Pool Setting 與網站設定,讓責起 Process 的服務能起依賴於這個 pool 的網站於 process 中,不同的 Application Pool 可以保證應用執行的隔離。(我有看到一個算是挺生活化的解釋,就如同游泳的水道,不同水道間會區隔開來,如果沒區隔開來就會變成一團混亂,就有點像這種感覺,Application Pool 就是保證於相依於它的網站/應用能隔離在同一個水道裡)
我們這篇只會簡單看一下基本設定,進階設定會抽另外一篇單獨講,基本設定有這些(透過在 Application Pool 的管理介面右上角可以新增新的 Application Pool):
Application 的名稱,.NET CLR version(相依於這個架在上面的網站版本決定這個進程起來的方式),還有 pipeline mode。
.NET CLR version 不是指一般我們在寫 C# 所使用的 .NET 版本,是運行時使用的函式庫版本,簡單區分的話 .NET framework 2.0,3.0,3.5 選擇 .NET CLR Version v2,而 .NET framework 4 和以後的版本則選擇 .NET CLR Version v4。
這邊勾選立刻啟動 application pool 並不是立刻起 process,而是讓 application pool 變成 start 的狀態,能夠依設定來處理 request,看是要建 request 還是其他動作─依 advance setting 中的設定才會決定相關 process 實際起來的時間點。
這邊花點篇幅講一下 pipeline mode 的兩個選擇:classic 和 integrated。
Pipeline mode 指的是處理 request 進來那一連串動作,一個一個的處理階段,如同一條管線這樣處理,這兩種選擇代表了不同的處理方式。
在 IIS 6.0 及以前版本,只有 classic 的模式,這個模式在處理 request 時只能夠透過 ISAPI extension 和 ISAPI filter。以 ASP.NET 來說,分別對應到 aspnet_isapi.dll 和 aspnet_filter.dll,裡面定義了怎麼去處理 ASP.NET 的請求,在這種情景下,其實 ASP.NET 和其他語言處理並沒有什麼太大的區別,都是直接透過 ISAPI 的方式來處理。
在 IIS 7+,這個模式是配合了環境下 IIS 的管道和 ASP.NET 的request 管道整合到了一塊,ASP.NET 可以看到它想看的 request 而不再是先由 IIS 依據類型作分配。從這個版本開始,它看上去不再像一個額外插件,更貼合了 IIS。
在這個模式下,ASP NET 的 HttpModule 能做到和 ISAPI filter 近乎一樣的事,HttpHandlers 則如 ISAPI extension 的角色一樣。在 Integrated Mode 裡就不再透過 ISAPI 這層來處理請求,可以省去一些重複的時間。
上面兩張圖來自官方文檔,可以清楚的看到兩者的運行邏輯差異,
如上面提到的 Classic 存在的目的更多是為了相容 6.0 以前的網站,在另外一篇官方文檔的搬遷升級指南中,其實更有詳述:今天如果你要將一個本來以 Classic 邏輯運行的網站改成 Integrated mode,你可能遇到的問題和 work around,在這篇文章裡其實你就可以清楚的看見個個差異與因應的改變。甚至 IIS 6.0 與 IIS 7 的 Classic mode 都還有些差異,雖然距離撰文的現在應該是有些久遠的以前了,如果你剛好需要做到這個版本升級與維護,務必注意這邊文章裡提的調整。
Integrated mode 的好處是將 IIS 和 ASP.NET 更緊密相接,如上面構造圖所畫,可以省去一些以前會重複在 IIS 和 ASP.NET 中重複做到的步驟。Module 的架構調整也能夠影響到更廣泛的類別,無論靜態或動態網頁,以往的作用多為 ASP.NET 如 ASPX 等網頁。這可以從第一張圖的 Determine Handler 拉出去的線看出來,本來部分類型是無法運行模組的,而現在透過 Execute Handler 階段的改動,Http Module 可以做用於所有類型的檔案上。
在選擇模式的時候,如果是新架設的網站,就都以 integrated mode 為主就可以了,除非你是在架設不熟悉的語言按照步驟,而他要求 classic mode,或是搬遷舊版(IIS 6/其他相依於設置為 classic mode 的 application pool 的網站)的網站到新的 Server,使用 classic mode 可以相容於部分舊設定,減少你需要調整與改動的幅度。如果想要做網站升級,那就參照上篇官方文檔的指南可以得到更詳細的除錯或差異比較/要注意的地方。
今天的內容大致到這裡,解釋了 application pool 的角色,為什麼我們需要 application pool,它的好處以及設置需要注意的地方。最後則帶到 application pool 中兩種管道模式的差異,解釋各個情境下的搭配使用組合。下一篇我們會來討論,這篇僅是帶過的觀念:Process 的起來,究竟是怎麼一回事、實際上當一個網站運行的時候,背後又有哪些支持他的服務。