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 伺服器,如圖是程序內託管圖。
![](https://img2020.cnblogs.com/blog/675038/202009/675038-20200909095949981-1530714998.png)
在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的方式有些相似。
![](https://img2020.cnblogs.com/blog/675038/202009/675038-20200909100001379-254434371.png)
此實現形式,應用會訪問本機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`值以下
```bash
OutOfProcess
```
然後就可以調整為程序外託管模式。
> 關於更多程序內和程序外的知識,可以檢視《深入淺出ASP.NET Core》的5.4章內容。
## West Wind WebSurge 測試
我準備了一個專案Demo,使用 West Wind WebSurge 軟體來測試下程序內與程序外專案的吞吐情況。
它還可以檢查伺服器的HTTP響應,並檢查Web伺服器Kestrel或Microsoft IIS作為Web伺服器:
### ASP.NET Core2.X 程序外(OutOfProcess)
![](https://img2020.cnblogs.com/blog/675038/202009/675038-20200909100019633-1257727598.png)
### ASP.NET Core2.X 程序內(Inprocess)
![](https://img2020.cnblogs.com/blog/675038/202009/675038-20200909100028775-1528106615.png)
## 效能對比
使用新的In Process模型的明顯原因是它更快,使用的資源更少,因為它直接在IIS應用程式池的過程中執行。沒有內部HTTP流量和開銷,請求將立即處理。
本次測試,僅僅是為了對比程序核心程序外的效能對比,不作為其他應用程式的抗負載能力的參考。
因為訪問的介面很簡單,請求僅表明可以大大提高潛在的吞吐量,但是對於長流程的請求和請求訪問時間,應用程式處理的開銷也增加,所以理性看待。
尋求高的效能始終是一個好主意,提供程式的吞吐量意味著更少的請求延遲,更快的響應時間以及更少的伺服器開銷,增加更多的負載能力。
我準備了一臺4核8G的筆記本,因為這檯筆記本裝了很多其他應用,因此產生的結果肯定不如伺服器的結果,現在開始進行測試。
### 程序內託管模式結果
![](https://img2020.cnblogs.com/blog/675038/202009/675038-20200909100038765-220761363.png)
上面的程序內託管模式,我們可以看到一共傳送了3.7W次請求,每秒633次請求的處理速度。
### 程序外託管模式結果
![](https://img2020.cnblogs.com/blog/675038/202009/675038-20200909100048019-1747002372.png)
切換為程序外後,一共處理了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
我建了個知識星球,希望能和更多的小夥伴交流,歡迎關注