ASP.NET Core 程式內與程式外的效能對比

角落的白板報發表於2020-09-09

ASP.NET Core 程式內與程式外的效能對比

本文內容是《深入去淺出ASP.NET Core》提供的擴充套件內容,畢竟在書裡說程式內外的效能說明對比,對於初學者而言,稍微複雜了點。

我在B站的視訊是基於.NET Core 2.2提供的案例,在書籍中提供的是.NET Core 3.1的案例。有人問,預設程式到底是程式外還是程式內。

ASP.NET Core 預設程式

ASP.NET Core 2.2 由預設的程式外,所以需要我們指定下專案檔案中的程式資訊。
而從ASP.NET Core 3.X開始,dotnet開發團隊又將它修改為了程式內。

所以請記住:

  • ASP.NET Core 2.X及以前預設是程式外託管
  • ASP.NET Core 3.X預設為程式內託管

我最近查詢了下,應該說最早.NET Core就不支援程式內,所以也是慢慢迭代到支援程式內的。

ASP.NET Core的程式內託管

使用 InProcess 託管,應用程式託管在 IIS 工作程式(w3wp.exe 或 iisexpress.exe)中。 只有一個 Web 伺服器,它是承載我們的應用程式的 IIS 伺服器,如圖是程式內託管圖。

在ASP.NET Core 2.2後,IIS上有了一個In Process託管模型,該模型直接在IIS應用程式池內部託管ASP.NET Core,而無需使用代理dotnet.exe執行.NET Core本機Kestrel Web伺服器的外部例項。

程式內模型不使用Kestrel,而是使用IISHttpServer()直接在IIS應用程式池內部託管的新Web伺服器實現,該實現與傳統的ASP.NET被引入IIS的方式有些相似。

此實現形式,應用會訪問本機IIS物件以建立建立的請求資料,並將HttpContext其傳遞到ASP.NET Core中介軟體管道。

當然這些都是.NET Core層面的處理,我們作為應用開發者,基本會去關心和留意它。

但是就是這個調整,大大的提高了ASP.NET Core在IIS上的請求吞吐量。

實際生產環境中InProces還是OutOfProcess

對於部署專案到IIS環境中,您幾乎肯定希望是採用InProcess模式進行託管,因為它提供了更好的效能,並且通常佔用的資源較少,因為它避免了IIS和Kestrel之間可能存在的網路抖動。

但是是其他場景下,我就推薦採用OutOfProcess模式了,比如:

  • 用於故障排除和除錯故障伺服器(例如,您可以在啟用控制檯日誌記錄,檢視更加詳細的資訊)。
  • 同一個應用程式實現100%相容,無論是部署在Windows還是Linux上,Kestrel的主要機制是可以處理所有平臺上的HTTP請求。
  • 使用InProcess模型時,則不會使用Kestrel服務(這個在我的書中有詳細說明),而是直接與IIS的請求管道中的模組進行通訊。

調整為程式外託管

我們可以通過修改專案檔案,配置AspNetCoreHostingModel值以下

<AspNetCoreHostingModel>OutOfProcess</AspNetCoreHostingModel >

然後就可以調整為程式外託管模式。

關於更多程式內和程式外的知識,可以檢視《深入淺出ASP.NET Core》的5.4章內容。

West Wind WebSurge 測試

我準備了一個專案Demo,使用 West Wind WebSurge 軟體來測試下程式內與程式外專案的吞吐情況。

它還可以檢查伺服器的HTTP響應,並檢查Web伺服器Kestrel或Microsoft IIS作為Web伺服器:

ASP.NET Core2.X 程式外(OutOfProcess)

ASP.NET Core2.X 程式內(Inprocess)

效能對比

使用新的In Process模型的明顯原因是它更快,使用的資源更少,因為它直接在IIS應用程式池的過程中執行。沒有內部HTTP流量和開銷,請求將立即處理。

本次測試,僅僅是為了對比程式核心程式外的效能對比,不作為其他應用程式的抗負載能力的參考。

因為訪問的介面很簡單,請求僅表明可以大大提高潛在的吞吐量,但是對於長流程的請求和請求訪問時間,應用程式處理的開銷也增加,所以理性看待。

尋求高的效能始終是一個好主意,提供程式的吞吐量意味著更少的請求延遲,更快的響應時間以及更少的伺服器開銷,增加更多的負載能力。

我準備了一臺4核8G的筆記本,因為這檯筆記本裝了很多其他應用,因此產生的結果肯定不如伺服器的結果,現在開始進行測試。

程式內託管模式結果

上面的程式內託管模式,我們可以看到一共傳送了3.7W次請求,每秒633次請求的處理速度。

程式外託管模式結果

切換為程式外後,一共處理了1.3W次請求,每秒是217次請求處理速度。

可以看到程式外的效能比程式內的較低。

再次說明,因為我的PC機中安裝了和執行了大量的其他應用,給予它測試的記憶體和CPU是不足夠的,感興趣的可以,自己進行測試。

最後

儘管IIS被不停的邊緣化以支援在Linux和Docker上託管,但請記住,如果釋出到
雲原生平臺,如Azure的WebAPP或者其他未明確指定的平臺,IIS依然是ASP.NET Core 部署的預設模型。這說明IIS確實還在很多場景中有廣泛的使用,因此它不會很快消失。微軟通過新增的程式內模型,提供更好的效能處理機制以此來增加對它的支援。

現在開始,我們有兩種選擇,

  • 可以使用OutofProcessing(通過IIS代理請求)並使用完全獨立的ASP.NET Core控制檯應用程式(通過基於.NET的Kestrel Web伺服器使用)託管在IIS上,
  • 也可以使用InProcess託管模型,它與經典ASP.NET通過其自身的本機API與IIS進行互動的方式更為相似。
  • In Process模型在請求吞吐量方面要快得多,因此在幾乎所有情況下,在IIS上託管時,您都希望選擇InProcess模型。

文章參考來源:https://weblog.west-wind.com/posts/2019/Mar/16/ASPNET-Core-Hosting-on-IIS-with-ASPNET-Core-22#check-the-response-server-header

案例原始碼地址:https://github.com/RickStrahl/AspetCoreIISInprocessHostingSample

我建了個知識星球,希望能和更多的小夥伴交流,歡迎關注哦。

相關文章