﻿# 介紹 IIS 8 全新的 HttpPlatformHandler 模組與 ASP.NET 5 Beta8 重大變更

[HttpPlatformHandler](http://www.iis.net/downloads/microsoft/httpplatformhandler) 是一個支援 IIS 8 與 IIS 8.5 的原生模組 (native module)，主要使用於 Microsoft Azure Websites 網站服務中，用途是讓 Java 或其他第三方程序可以輕鬆整合到 IIS 之中，讓各種 Web 框架都能直接掛載到 IIS 之上。而近期發佈的 [ASP.NET 5 Beta8](https://devblogs.microsoft.com/dotnet/announcing-availability-of-asp-net-5-beta8/) 版本也正式宣告改採 [HttpPlatformHandler](http://www.iis.net/downloads/microsoft/httpplatformhandler) 模組搭配 [Kestrel HTTP Server](https://github.com/aspnet/KestrelHttpServer) 執行 ASP.NET 5 應用程式，想要了解其內部運作結構，必須得了解一下。

基本上 HttpPlatformHandler 主要做兩件事：

1.  **Process Management of http listeners**  
    任意第三方程序原本需要監聽 (listen) 可接受 HTTP 要求的通訊埠 (Port)，都改交由 IIS 來接受要求。  
    例如 Tomcat, Jetty, Node.exe, Ruby 等等，當然 ASP.NET 5 的 Kestrel 也是屬於這個類型的程序。
2.  **Proxy requests to the process that it manages**  
    將那些交由 IIS 代理監聽的 HTTP 要求轉發到被管理的第三方程序。

簡單來說，原本你可能可以直接用 Node.js 或 Ruby 來執行網站，Node.js 或 Ruby 原本就能監聽 (listen) 通訊埠 (Port)，但如果 Node.js 或 Ruby 掛掉的話，網站也就死了。不過若想透過 IIS + [HttpPlatformHandler](http://www.iis.net/downloads/microsoft/httpplatformhandler) 來管理者些程序，優點就是所有接聽 HTTP 要求的任務都改由 IIS 負責，並且由 IIS 啟動第三方程序 ( 例如 Node.js 或 Ruby )，然後由 IIS 將這些 HTTP 要求轉發到第三方程序中。如果第三方程序掛掉了，IIS 就會視同沒有執行這個程序，並且自動重新啟動第三方程序。

HttpPlatformHandler 模組的設定主要設定在 web.config 或 applicationHost.config 設定檔裡，主要設定在 **<system.webServer>** 區段下，詳細的設定方法可參考 [HttpPlatformHandler Configuration Reference](http://www.iis.net/learn/extensions/httpplatformhandler/httpplatformhandler-configuration-reference) 文件。

我們可以來看看幾個的設定範例：

**1\. ASP.NET 5**

```
<configuration>  <system.webServer>    <handlers>      <add name="httpplatformhandler"            path="*"            verb="*"            modules="httpPlatformHandler"            resourceType="Unspecified" />    </handlers>    <httpPlatform         processPath="..\approot\web.cmd"         arguments=""         stdoutLogEnabled="false"         stdoutLogFile="..\logs\stdout.log"         startupTimeLimit="3600">    </httpPlatform>  </system.webServer></configuration>
```

**2\. Tomcat (Java)**

```
<configuration>  <system.webServer>    <handlers>      <add name="httpplatformhandler"            path="*"            verb="*"            modules="httpPlatformHandler"            resourceType="Unspecified"/>    </handlers>    <httpPlatform processPath="c:\dev\javasites\bin\apache-tomcat-8.0.15\bin\startup.bat"                   arguments=""                   stdoutLogEnabled="true"                   stdoutLogFile="\\?c:\dev\javasites\log.txt">      <environmentVariables>        <environmentVariable name="JRE_HOME" value="%programfiles%\java\jdk1.8.0_25" />        <environmentVariable name="CATALINA_OPTS" value="-Dport.http=%HTTP_PLATFORM_PORT% -Dsomeotherconfig=value"/>        <environmentVariable name="CATALINA_HOME" value="c:\dev\javasites\bin\apache-tomcat-8.0.15" />      </environmentVariables>    </httpPlatform>  </system.webServer></configuration>
```

**3\. Jetty (Java)**

```
<configuration>  <system.webServer>    <handlers>      <add name="httpplatformhandler"            path="*"            verb="*"            modules="httpPlatformHandler"            resourceType="Unspecified"/>    </handlers>      <httpPlatform processPath="c:\Program Files\Java\jdk1.8.0_25\bin\java.exe"                     arguments="-Djava.net.preferIPv4Stack=true -Djetty.port=%HTTP_PLATFORM_PORT% -Djetty.base=&quot;c:\dev\javasites\bin\jetty-distribution-9.2.6.v20141205&quot; -jar &quot;c:\dev\javasites\bin\jetty-distribution-9.2.6.v20141205\start.jar&quot;"                     startupTimeLimit="20"                     startupRetryCount="20"                     stdoutLogEnabled="true">      </httpPlatform>  </system.webServer></configuration>
```

從以上幾個設定範例可以看出，其實 HttpPlatformHandler 的架構非常單純，就是由 IIS 幫你管理第三方程序，啟動第三方程序時，可直接設定啟動的程序 (processPath)、參數 (arguments) 與一些啟動參數，例如啟動時間限制 (startupTimeLimit)、啟動重試次數上限 (startupRetryCount)、是否輸出記錄到 stdout 管線中 (stdoutLogEnabled)、是否將輸出寫入到檔案中 (stdoutLogFile)、…等等，當然，必要的時候還可以設定額外的 **環境變數** (environmentVariables) 給第三方程序使用。

### 關於 ASP.NET 5 Beta8 的重大變更

在 ASP.NET 5 發展的早期，有個 Helios 專案負責讓全新的 ASP.NET 5 框架能夠執行在 IIS 之上，這個 Helios 專案 (包含在 Microsoft.AspNet.Server.IIS 套件中) 主要用途是將 DNX 與 CLR 掛載到 System.Web hosting model 之中，在網站啟動之後動態抽換掉正在執行的 Runtime，改由 DNX 與 CoreCLR 來執行程式。這也意味著在 System.Web hosting model 與 DNX hosting model 有許多邏輯是重疊的，而日後在維護 ASP.NET 5 框架時勢必引發更複雜的實作，也很難維護兩個 hosting model 之間的一致性，因此微軟決定在 ASP.NET 5 Beta8 開始將 Helios 退役。

Helios 退役之後，便改用效能更好的 [Kestrel](https://github.com/aspnet/KestrelHttpServer) 來執行 ASP.NET 5 應用程式，這個 [Kestrel HTTP Server](https://github.com/aspnet/KestrelHttpServer) 基於 跨平台 的 [libuv](https://github.com/libuv/libuv) 函式庫，這個 [libuv](https://github.com/libuv/libuv) 函式庫採用非同步 I/O 架構，常用於 Node.js 之中，執行效能極佳，你可以看看 [ASP.NET 5 Benchmarks](https://github.com/aspnet/benchmarks) 頁面最後的 **Plain Text with HTTP Pipelining** 測試數據，ASP.NET 5 on Kestrel 的壓力測試竟然可以測出每秒 443,528 個要求，這實在是個非常驚人的數字！

當然，你要知道 [Kestrel](https://github.com/aspnet/KestrelHttpServer) 本身就是一台 HTTP 伺服器，不需要 IIS 也能運作，並且可在 Windows, Linux, OS X 上面跨平台執行。

只是在 Windows 平台上，你可以利用 IIS 搭配 HttpPlatformHandler 來執行，讓 IIS 幫你管理 Kestrel 程序，安全性與穩定度都將會大幅提高，不過唯一的缺點就是會犧牲掉一些效能，畢竟經由 IIS 代理所有的 HTTP 要求，這當中多少會有所損耗，但我認為這點損耗可以靠 **橫向擴展** (Scale Out) 來解決，所以這是可以接受的權衡措施 (Trade-off)。

另外，使用 IIS / HttpPlatformHandler  搭配 Kestrel 來執行 ASP.NET 5 還有許多優點：

1.  你的 IIS 應用程式集區不需要載入任何 Managed 程式碼，甚至於完全不用設定載入 CLR 就可以執行網站。( 因為所有 HTTP 要求都被轉送到 Kestrel 處裡 )  
    ![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/1fd3984cf3afe4a4dda4-image_2748.png)
2.  因為應用程式集區不需要載入 CLR，因此也不需要事先安裝 ASP.NET 相關元件。如下圖示，這就不一定要安裝了：  
    ![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/2a626330013a91a014d2-image_2749.png)
3.  你原本的 ASP.NET 4.x 模組依然可以跑在 IIS 上面，就算你有啟用 HttpPlatformHandler 也完全不影響原本 IIS 模組的執行，因為 ASP.NET 4 與 ASP.NET 5 隸屬於完全不同的執行程序。
4.  由於你可以在 web.config 中透過 HttpPlatformHandler 設定**環境變數**，因此你可以透過 web.config 即可控制 ASP.NET 5 的 **Environment** 屬性值，只要透過設定檔就可以控制 ASP.NET 5 的執行過程。( 例如切換 Staging 或 Production 等模式，這些模式都可以自由設定，詳細說明可參考 ASP.NET 5 的 [Working with Multiple Environments](https://docs.asp.net/en/latest/fundamentals/environments.html) 文件 )
5.  在多台伺服器之間使用一致的標準，處裡第三方程序的啟動錯誤。
6.  一致的程式碼與執行過程：

-   無論你透過 self-hosted 或 IIS 執行 .NET Framework (full CLR) 時，都支援 app.config 設定檔讀取。 (ASP.NET 5 已經不再需要讀取 web.config 設定檔)
-   設定與使用服務元件時更加一致 ( Startup.cs )
-   一致的啟動過程 ( 不再有詭異的 bin\\AspNetLoader.dll 檔案 )

最後，你若從 Visual Studio 2015 建立 ASP.NET 5 Beta8 專案，可以看到在 wwwroot\\web.config 這個檔案

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/dc92d2962e59a3cd918b-image_2750.png)

該檔案定義了 **<httpPlatform>** 設定，並在 processPath 與 arguments 放入了變數，這個變數會交由 Visual Studio 2015 進行管理，當在發佈網站時，會透過 **dnu publish** 命令，搭配 **\--iis-command** 選項進行變更。

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/945d760bb9ef53c50118-image_2751.png)

更詳盡的討論可以參考 [Change to IIS hosting model · Issue #69 · aspnet/Announcements](https://github.com/aspnet/Announcements/issues/69) 網頁說明。

備註：未來所有 ASP.NET 5 的重大變更都會公告在 [Issues · aspnet/Announcements](https://github.com/aspnet/Announcements/issues) 這裡。

**相關連結**

-   [HttpPlatformHandler for IIS 8+ Download](http://www.iis.net/downloads/microsoft/httpplatformhandler)
-   [HttpPlatformHandler Configuration Reference : The Official Microsoft IIS Site](http://www.iis.net/learn/extensions/httpplatformhandler/httpplatformhandler-configuration-reference)
-   [Upload a custom Java Website to Azure Websites](https://learn.microsoft.com/en-us/azure/app-service/configure-language-java-deploy-run) – Examples of how to configure the HttpPlatformHandler with Jetty, Hudson and Liferay
-   [HttpPlatformHandler Forum](http://forums.iis.net/1173.aspx)
-   [Announcing Availability of ASP.NET 5 Beta8 - .NET Web Development and Tools Blog](https://devblogs.microsoft.com/dotnet/announcing-availability-of-asp-net-5-beta8/)
-   [ASP.NET 5 Beta8 Release Notes](https://github.com/aspnet/Home/releases/tag/v1.0.0-beta8)
-   [Known issues for ASP.NET 5 support in Visual Studio 2015](https://github.com/aspnet/Tooling/blob/master/known-issues-vs2015.md)
-   [Change to IIS hosting model · Issue #69 · aspnet/Announcements](https://github.com/aspnet/Announcements/issues/69)
-   [Working with Multiple Environments — ASP.NET 0.0.1 documentation](https://docs.asp.net/en/latest/fundamentals/environments.html)
-   [ASP.NET 5 Schedule and Roadmap](https://github.com/aspnet/Home/wiki/Roadmap)
-   [Upgrading from ASP.NET 5 Beta 7 to Beta 8](http://wildermuth.com/2015/10/20/Upgrading_from_ASP_NET_5_Beta_7_to_Beta_8)
