只有累積,沒有奇蹟

2019年3月17日 星期日

[.NETCore] ASP.NET Core - Kestrel Web Server

前言
上一篇分享了如何在 IIS 執行 ASP.NET Core 專案,其中 Kestrel 關鍵字一直不斷的在文章中被提到,Kestrel 可以說 .NET Core 在跨平台中扮演相當重要的角色,在研究 Kestrel 相關知識時發現在 MSDN 中有篇文章介紹 Kestrel web server implementation in ASP.NET Core 十分清楚,以下就分享閱讀完文章後的理解與說明,若有問題歡迎提出一起討論或是給予指導。

Kestrel 是什麼? 可以吃嗎
Kestrel 是一個 ASP.NET Core 跨平台 web server,開源 OpenSource、輕量級的服務;底層運作是 libuv 函式庫,此函示庫主要以 Node.js 開發支援多平台且著重非同步 I/O 處理,在建立新的 ASP.NET Core 應用程式預設情況下,是以  Kestrel Web Server  作為預設的 Web Server 服務來處理 Web Request 請求。

Kestrel Web Server 的特性如下
  • 跨平台,可以在 Windows、Linux、MacOS 上運作
  • 支援 HTTPS 以及 HTTP/2
  • 支援 SSL
  • 不支援多個應用程式用相同 Port
為何選擇 Kestrel
IIS 是一個功能豐富且高效 Web Server,提供方便的操作設定 SSL、HTTP2、gzip、UrlRewrite 等功能,但 IIS Server 強大的功能僅限在 Windows 上使用,無法在非 Windows 的 OS 執行;ASP.NET Core 主要訴求之一是可以跨平台運行,需要在不同 web server 執行 ASP.NET Core 應用程式,像是 Nginx,Apache 等非 IIS Server 服務。Kestrel 是一個輕量級的 Web Server,可以在不同的平台執行像是 Linux、MacOS 及 Windows 環境也因此 ASP.NET Core 應用程式會使用 Kestrel web server 作為 In-process 服務器的原因。

Self & Proxy Server
Kestrel web server 可以 單獨使用 ,也可以當做  反向代理  (reverse proxy server),在搭配 IIS、Nginx 或是 Apache,當反向代理收到 Http Request 請求時會轉發給 Kestrel web server 進行處理,以下就針對兩者做簡單的介紹

單獨使用
Kestrel 單獨使用時可以當作 Web Server 直接對外處理來自 Internet 的請求,也可以針對接收的 HTTP Request 請求做設定的動作,這部分稍後會提到。


反向代理
Kestrel web server 是一個輕量級的 Web Server 服務,並沒有像 IIS 或是 Apache 提供面對 Internal 的 Web 服務器完整功能,因此建議將應用程式佈署在 IIS、Ngunx、Apache 等服務器上以提高安全性,當一個 HTTP Request 請求進來時會先到 Web Server 充當代理,在將 Request 請求轉發到 Kestrel web server 進行處理;流程如下

另外 Kestrel 不支援共用 port 的機制,詳細可以參考 MSDN 說明 : 傳送門

使用 Kestrel
從 .NET Core 2.1 之後的版本支援 Microsoft.AspNetCore.App metapackage,其中就有包含 Microsoft.AspNetCore.Server.Kestrel package。

上述有提到,在建立一個新的 ASP.NET Core 專案時預設用 Kestrel 當作 Web Server,開啟新的專案後打開 Program.cs 檔案,預設產生好的 code template 為  CreateDefaultBuilder 方法,代碼如下
接著在繼續追下去,可以從 CreateDefaultBuilder() 說明得知此方法背後是使用  Kestrel  做為 WebServer
Kestrel 為一個輕量級的 Web Server,提供  ConfigureKestrel 方法可以讓開發者進行調整 (.NET Core 2.2)
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .ConfigureKestrel((context, options) =>
        {
            // Set properties and call methods on options
        });
另一種使用方式也可以直接 new WebHostBuilder instance,使用 UseKestrel 指定使用 Kestrel web server
public static void Main(string[] args)
{
    var host = new WebHostBuilder()
        .UseContentRoot(Directory.GetCurrentDirectory())
        .UseKestrel()
        .UseIISIntegration()
        .UseStartup<Startup>()
        .ConfigureKestrel((context, options) =>
        {
            // Set properties and call methods on options
        })
        .Build();

    host.Run();
}

w3wp.exe v.s dotnet.exe 
在傳統的 ASP.NET 與 ASP.NET Core 應用程式在 IIS 中運作機制不相同,以下就自己理解的部分簡單介紹兩者差異,如有謬誤也請給指導與一起討論

ASP.NET 
在一般 IIS 中 ASP.NET 應用程式,當站台執行後會起一個  w3wp.exe  的 Worker Process 在 IIS Application Pool,舉例來說在 IIS 建立一個名為 WebAPI 站台並設定其應用程式集區及 Port,Web Server 服務啟動後可以看到會有個 w3wp.exe Process 對應到其服務,如下圖所示

ASP.NET Core
在 ASP.NET Core 中則是獨立的 console Application 透過  dotnet  otnet runtime command,不會加載到 IIS Worker Process 中,當有個請求來時會透過  AspNetCoreModule  呼叫外部的 .NET Core Console Application,在 IIS 執行 ASP.NET Core 應用程式設定方式可以參考上一篇文章 : 傳送門,舉例來說在 IIS執行.NET Core 應用程式後可以在工作管理員觀察到會比 ASP.NET 多 dotnet process,如下所示

更詳細的介紹可以參考 Rick Strahl 好文 : Publishing and Running ASP.NET Core Applications with IIS

Kestrel option 設定
Kestrel 為 web server 相對的也提供一些 Server 設定,這些設定對於 Kestrel 單獨使用直接對 Internal 時是很實用的,舉例說可以設定 TCP 最大連線數、限制 Request body 最大 size、每個連線的最大流量限制...等設定,需要透過  ConfigureKestrel 方法進行設定參數內容,如果有需要更進一步的設定需求可以參考 Kestrel option 說明,相信 MSDN 有更詳細的說明這裡就不在多做介紹 

後記
在開始研究 ASP.NET Core 之後發現很多觀念與過去的都不盡相同,必須拋棄過去在 ASP.NET 開發與設計的思維方式,像是 Kestrel Web server 是為了在不同的 OS 執行 .NET Core 應用程式所新制訂的 Web Server,但其變化速度也是蠻快的,在研究時版本已經從.NET Core 2.2 改到 3.0,在研究過程中還發現 Kestrel 與 IIS 整合部分可以透過 web.config 切換 OutOfProcess 或是 InProcess 設定加快其效能,感覺也是個有趣可以深入研究的議題,希望之後有機會可以追上 .NET Core 更新的腳步 XD

參考
Kestrel web server implementation in ASP.NET Core
More-on-ASPNET-Core-Running-under-IIS

0 意見:

張貼留言

Copyright © m@rcus 學習筆記 | Powered by Blogger

Design by Anders Noren | Blogger Theme by NewBloggerThemes.com