ASP.NET Core高性能服務器HTTP.SYS

如果我們只需要將ASP.NET CORE應用部署到Windows環境下,并且希望獲得更好的性能,那么我們選擇的服務器類型應該是HTTP.SYS。Windows環境下任何針對HTTP的網絡監聽器/服務器在性能上都無法與HTTP.SYS比肩。[本文節選《ASP.NET Core 6框架揭秘》第18章]

一、HTTP.SYS簡介
二、MessagePump & UseHttpSys
三、HttpSysOptions

一、HTTP.SYS簡介

HTTP.SYS本質上就是一個HTTP/HTTPS監聽器,它是Windows網絡子系統的一部分,是一個在內核模式下運行的網絡驅動。HTTP.SYS對應的驅動文件為“%WinDir\System32\drivers\http.sys”,不要小看這個只有1M多的文件,Windows系統針對HTTP的監聽、接收、轉發和響應大都依賴它。如圖1所示,HTTP.SYS建立在Windows網絡子系統針對TCPIP協議棧的驅動(TCPIP.SYS)之上,并為用戶態運行的IIS提供基礎的HTTP通信服務。前面我們使用的HttpListener也建立在HTTP.SYS上面。

234f397274c0ea8990d950d00238e4ab.png
圖1 HTTP.SYS

由于HTTP.SYS是在操作系統內核態運行,所以它提供的性能優勢是其他在用戶態運行的同類產品無法比擬的。由于它自身提供響應緩存,所以在緩存命中的情況下根本不需要與用戶態進程進行交互。它還提供了請求隊列(Request Queue),如果請求的目標進程(比如IIS的工作進程)處于活動狀態,它可以直接將請求分它給它,否則請求會暫存于隊列中等待目標進程來提取,這樣的工作模式既減少了內核態與用戶態之間的上下文切換,也確保請求不會丟失。HTTP.SYS還提供連接管理,流量限制,診斷日志等功能,并提供針對Kerberos的Windows認證。

由于HTTP.SYS是一個底層共享的網絡驅動,它有效地解決了端口共享的問題。用戶態進程會使用地址前綴(含端口號)“接入”HTTP.SYS,后者利用提供的地址前綴來轉發請求,多個用戶態進程只要保證提供的地址前綴不同就可以了,所以它們可以使用相同的端口號。端口共享使每個用戶進程都可以使用標準的80/443端口。

二、MessagePump & UseHttpSys

基于HTTP.SYS的服務器體現為如下這個MessagePump類型,它內部使用一個HttpSysListener對象采用注冊的監聽地址接入HTTP.SYS。MessagePump提供針對HTTP 1.X、HTTP 2以及HTTPS的支持。對于Windows Server 2022和Windows 11,還支持HTTP 3。IWebHostBuilder接口如下這兩個UseHttpSys擴展方法用來完成針對MessagePump的注冊。

internal?class?MessagePump?:?IServer,?IDisposable
{internal?HttpSysListener?Listener?{?get;?}public?IFeatureCollection?Features?{?get;?}public?MessagePump(IOptions<HttpSysOptions>?options,?ILoggerFactory?loggerFactory,IAuthenticationSchemeProvider?authentication);public?Task?StartAsync<TContext>(IHttpApplication<TContext>?application,CancellationToken?cancellationToken);public?Task?StopAsync(CancellationToken?cancellationToken);public?void?Dispose();
}public?static?class?WebHostBuilderHttpSysExtensions
{[SupportedOSPlatform("windows")]public?static?IWebHostBuilder?UseHttpSys(this?IWebHostBuilder?hostBuilder);[SupportedOSPlatform("windows")]public?static?IWebHostBuilder?UseHttpSys(this?IWebHostBuilder?hostBuilder,Action<HttpSysOptions>?options);
}

如下所示的是在Minimal API下調用UseHttpSys注冊MessagePump 服務器的例子。

var?builder?=?WebApplication.CreateBuilder(args);
builder.WebHost.UseHttpSys();
var?app?=?builder.Build();
app.MapGet("/",?()?=>?"Hello?World");
app.Run();

三、HttpSysOptions

在調用UseHttpSys擴展方法注冊基于HTTP.SYS的MessagePump服務器的時候,我們可以利用提供的Action<HttpSysOptions>委托對相關的配置選項進行設置。HttpSysOptions的UrlPrefixes屬性返回注冊的監聽地址前綴,但是最終是否這種直接注冊到服務器上的監聽器地址,取決于IServerAddressesFeature特性的PreferHostingUrls屬性,這一點與KestrelServer是一致的。

public?class?HttpSysOptions
{public?UrlPrefixCollection?UrlPrefixes?{?get;?}public?RequestQueueMode?RequestQueueMode?{?get;?set;?}public?string??RequestQueueName?{?get;?set;?}public?long?RequestQueueLimit?{?get;?set;?}public?AuthenticationManager?Authentication?{?get;?}public?ClientCertificateMethod?ClientCertificateMethod?{?get;?set;?}public?long??MaxConnections?{?get;?set;?}public?long??MaxRequestBodySize?{?get;?set;?}public?int?MaxAccepts?{?get;?set;?}public?Http503VerbosityLevel?Http503Verbosity?{?get;?set;?}public?TimeoutManager?Timeouts?{?get;?}public?bool?AllowSynchronousIO?{?get;?set;?}public?bool?EnableResponseCaching?{?get;?set;?}public?bool?ThrowWriteExceptions?{?get;?set;?}public?bool?UnsafePreferInlineScheduling?{?get;?set;?}public?bool?UseLatin1RequestHeaders?{?get;?set;?}
}

HTTP.SYS利用請求隊列來存放待處理的請求,我們可以利用RequestQueueMode屬性決定創建一個新的隊列或者使用現有的隊列。該屬性類型為如下這個RequestQueueMode枚舉,枚舉項Create表示創建新的隊列,Attach表示使用現有的以RequestQueueName屬性命名的對象,如果該隊列不存在會拋出異常。CreateOrAttach提供了一個折中方案,如果指定名稱的隊列不存在就創建一個以此命名的新隊列。該屬性的默認值為Create,RequestQueueName屬性默認值為Null(代表匿名隊列),RequestQueueLimit屬性表示隊列的容量,默認值為1000。HttpSysOptions承載的很多配置選項只會應用到新創建的請求隊列上。

public?enum?RequestQueueMode
{Create,Attach,CreateOrAttach
}

HttpSysOptions的Authentication屬性返回一個AuthenticationManager對象,我們利用它完成針對認證的設置。我們可以利用Schemes屬性設置認證方案,該屬性默認為None。如果不允許匿名訪問,可以將AllowAnonymous屬性設為False。如果將AutomaticAuthentication屬性返回True(默認值),認證用戶將自動賦值給HttpContext上下文的User屬性。AuthenticationDisplayName屬性用來為認證方案提供一個顯示名稱。

public?sealed?class?AuthenticationManager
{public?AuthenticationSchemes?Schemes?{?get;?set;?}public?bool?AllowAnonymous?{?get;?set;?}public?bool?AutomaticAuthentication?{?get;?set;?}public?string??AuthenticationDisplayName?{?get;?set;?}
}[Flags]
public?enum?AuthenticationSchemes
{None?=?0x0,Digest?=?0x1,Negotiate?=?0x2,Ntlm?=?0x4,Basic?=?0x8,Anonymous?=?0x8000,IntegratedWindowsAuthentication?=?0x6
}

HTTPS站點可以要求提供證書來對其實施認證,HttpSysOptions的ClientCertificateMethod屬性用于設置請求客戶端證書的方式,該屬性返回如下這個ClientCertificateMethod枚舉。在.NET 5之前,客戶端證書采用Renegotation的方式來提取的,Renegotiation是在已經建立的SSL/TLS連接上再次發起的一輪“協商握手”,這種方式對應AllowRenegotation枚舉項。由于可能帶來一些性能和死鎖的問題,這種方式在.NET 5之后已經默認禁止了,目前默認的方式是創建SSL/TLS連接的初始階段就提取該證書,這種方式對應AllowRenegotation枚舉項,這也是ClientCertificateMethod屬性的默認值。

public?enum?ClientCertificateMethod
{NoCertificate,AllowCertificate,AllowRenegotation
}

HttpSysOptions的MaxConnections和MaxRequestBodySize屬性分別表示最大連接數和請求主體內容的最大字節數,如果它們被設置為Null,意味著忽略對應的限制。這兩個屬性的默認值分別Null和30,000,000。MaxAccepts屬性表示接受的最大并發請求,默認值為當前處理器數量的5倍。如果并發請求數量超過限流設置,后續請求會拒絕處理,此時服務器會直接回復一個狀態碼為503的響應,與此同時還會根據Http503Verbosity屬性設置的等級作相應的處理。如果該屬性值為Basic(默認值),當前TCP連接會重置,Full和Limitmed選項會影響響應的狀態描述,前者返回詳細的Reason Phrase,后者采用標準的“Service Unavailable”。

public?enum?Http503VerbosityLevel
{Basic,Limited,Full
}

HttpSysOptions的Timeouts屬性返回如下這個TimeoutManager對象,我們利用它完成各種超時設置,包括請求主體內容抵達時間(EntityBody)、讀取請求主體內容時間(DrainEntityBody),請求在隊列中存放的時間(RequestQueue)、連接閑置時間(IdleConnection)和解析請求報頭時間(HeaderWait),這些超時時間默認都是兩分鐘。MinSendBytesPerSecond屬性表示響應數據的最小發送率,默認為每秒150字節。

public?sealed?class?TimeoutManager
{public?TimeSpan?EntityBody?{?get;?set;?}public?TimeSpan?DrainEntityBody?{?get;?set;?}public?TimeSpan?RequestQueue?{?get;?set;?}public?TimeSpan?IdleConnection?{?get;?set;?}public?TimeSpan?HeaderWait?{?get;?set;?}public?long?MinSendBytesPerSecond?{?get;?set;?}
}

HttpSysOptions還定義了其他一系列屬性。AllowSynchronousIO屬性(默認為False)表示是否運行以同步IO的方式完成針對請求和響應主體內容的讀寫。EnableResponseCaching屬性(默認為True)表示允許響應緩存。ThrowWriteExceptions屬性(默認為False)表示因斷開連接導致寫入響應主體內容失敗是否需要拋出異常。如果將UnsafePreferInlineScheduling(默認為False)設置為True,意味著會直接在讀取請求的IO線程中執行后續的應用代碼,否則我們編寫的應用代碼會分發到線程池中進行處理。這樣可以通過避免線程切換減少單個請求的處理耗時,但是會對整體的吞吐量帶來負面影響。UseLatin1RequestHeaders屬性(默認為False)表示是否采用Latin1字符集(ISO-8859-1)對請求報頭進行編碼。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/282375.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/282375.shtml
英文地址,請注明出處:http://en.pswp.cn/news/282375.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

神經網絡- receptive field

記錄一下感受野的理解&#xff1a; 在神經網絡中&#xff0c;感受野的定義是&#xff1a; 神經網絡的每一層輸出的特征圖&#xff08;Feature ap&#xff09;上的像素點在原圖像上映射的區域大小。 1. 神經網絡中&#xff0c;第一個卷積層的 感受野大小&#xff0c;就等于filt…

734. [網絡流24題] 方格取數問題 二分圖點權最大獨立集/最小割/最大流

問題描述&#xff1a;在一個有m*n 個方格的棋盤中&#xff0c;每個方格中有一個正整數。現要從方格中取數&#xff0c;使任意2 個數所在方格沒有公共邊&#xff0c;且取出的數的總和最大。試設計一個滿足要求的取數算法。編程任務&#xff1a;對于給定的方格棋盤&#xff0c;按…

Nginx 基礎 ( 二)

一、HTTP請求 http請求包括客戶端請求服務端 以及 服務端響應數據回客戶端&#xff0c;如下 請求&#xff1a;包括請求行、請求頭部、請求數據 響應&#xff1a;包括狀態行、消息報頭、響應正文 比如在Linux中curl請求網站獲取請求信息和響應信息 curl -v http://www.kugou.com…

《金融行業應用解決方案白皮書》發布,金融自主創新未來可期!

日前&#xff0c;以“聚勢賦能 行業共創”為主題的金融行業解決方案發布會在線上舉行。麒麟軟件發布《金融行業應用解決方案白皮書》&#xff0c;并發起成立“金融機具生態圈俱樂部”&#xff0c;助力金融行業用戶高質量發展。金融信息系統曾經被國外廠商壟斷金融信息系統作為國…

leetcode53 Maximum Subarray 最大連續子數組

題目要求 Find the contiguous subarray within an array (containing at least one number) which has the largest sum.For example, given the array [-2,1,-3,4,-1,2,1,-5,4], the contiguous subarray [4,-1,2,1] has the largest sum 6.即&#xff1a;尋找數列中的一個子…

黑馬程序員-WEB前端與移動開發就業班

Web前端 — IT互聯網的“門面”有人的地方就有江湖&#xff0c;有網站的地方就有Web前端&#xff0c;無所不用&#xff0c;互聯網大勢所在。課程循序漸進&#xff0c;技術小白課快速上手課程結構由淺入深&#xff0c;基礎課程講解充分&#xff0c;了解網頁的結構組成、分析頁面…

詳解go語言的array和slice 【二】

上一篇 詳解go語言的array和slice 【一】已經講解過,array和slice的一些基本用法&#xff0c;使用array和slice時需要注意的地方&#xff0c;特別是slice需要注意的地方比較多。上一篇的最后講解到創建新的slice時使用第三個索引來限制slice的容量&#xff0c;在操作新slice時…

詳解Objective-C的meta-class

2019獨角獸企業重金招聘Python工程師標準>>> 比較簡單的一篇英文&#xff0c;重點是講解meta-class。翻譯下&#xff0c;加深理解。 原文標題&#xff1a;What is a meta-class in Objective-C? 原文地址&#xff1a;http://www.cocoawithlove.com/2010/01/what-is…

Nginx 模塊的使用

Nginx模塊的使用,就是在Nginx配置文件中的http、server、location中添加參數&#xff0c;進行多一項或幾項處理一、 實現響應內容替換 1、sub_module二、Nginx的請求限制 1、連接頻率限制 limit_conn_module 2、請求頻率限制 limit_req_module 注: HTTP請求建立在一次…

Question | 網站被黑客掃描撞庫該怎么應對防范?

本文來自網易云社區在安全領域向來是先知道如何攻&#xff0c;其次才是防。針對題主的問題&#xff0c;在介紹如何防范網站被黑客掃描撞庫之前&#xff0c;先簡單介紹一下什么是撞庫。撞庫是黑客通過收集互聯網已泄露的用戶和密碼信息&#xff0c;生成對于的字典表&#xff0c;…

十倍程序員 | 使用 Source Generator 將 JSON 轉換成 C# 類

前言有時候&#xff0c;我們需要將通過 WebAPI 接收 JSON 字符串轉換成 C# 代碼。Visual Studio 提供了一個功能菜單可以輕松實現&#xff1a;執行完成后&#xff0c;它會將生成的代碼放在打開的的代碼窗口中。但是&#xff0c;如果有多個 JSON 字符串需要轉換&#xff0c;這個…

Delphi對話框初始地址InitialDir

我的電腦&#xff1a;SaveDialog1.InitialDir : ::{20D04FE0-3AEA-1069-A2D8-08002B30309D};// My Computer {20D04FE0-3AEA-1069-A2D8-08002B30309D}// Network Neighborhood {208D2C60-3AEA-1069-A2D7-08002B30309D}// Recycled {645FF040-5081-101B-9F08-00AA002F954E} 另外…

[python] 解決pip install download速度過慢問題 更換豆瓣源

""" python建立pip.ini.py 2016年4月30日 03:35:11 codegay """import osini"""[global] index-url https://pypi.doubanio.com/simple/ [install] trusted-hostpypi.doubanio.com """ pippathos.environ["…

Maven組件通過命令上傳本地和私有倉庫

安裝本地包到本地倉庫&#xff1a;mvn install:install-file -DgroupIdcom.xxx -DartifactIdmqtt-server-client -Dversion1.0.1 -Dpackagingjar -DfileE:\__vdt\MVVP\mqtt-server-client-1.0.1.jar -DpomFileE:\__vdt\MVVP\pom.xml安裝本地包到私有倉庫&#xff1a;mvn deploy…

Nginx -靜態資源Web服務

一、靜態資源類型 注&#xff1a;非服務器動態生成的文件 1、瀏覽器端渲染 HTML、css、js 2、圖片 jpeg、gif、png 3、視頻 flv、MPEG 4、文件 TXT、等任意下載文件二、靜態資源服務配置1、配置語法-文件讀取 syntax&#xff1a;sendfile on|off default&#xff1a;sendfi…

微軟Microsoft Azure 機器學習工作室的案例之Image Classification using DenseNet

點擊上方藍字關注我們&#xff08;本文閱讀時間&#xff1a;10分鐘)Microsoft Azure Machine Learning Studio是微軟強大的機器學習平臺&#xff0c;在設計器中&#xff0c;微軟內置了15個場景案例&#xff0c;但網上似乎沒有對這15個案例深度刨析的分析資料&#xff0c;所以我…

java小基礎之instanceof運算符

instanceof主要用來判斷一個類是否實現了某個接口&#xff0c;或者判斷一個實例對象是否屬于一個類。 1. 判斷一個對象是否屬于一個類 boolean result p instanceof Student; 2. 對象類型強制轉換前的判斷 Person p new Student(); //判斷對象p是否為Student類的實例 if(p in…

音樂分類

代碼&#xff1a; 1 import numpy as np2 from scipy import fft3 from scipy.io import wavfile4 from sklearn.linear_model import LogisticRegression5 import random6 """7 使用logistic regression處理音樂數據&#xff0c;音樂數據訓練樣本的獲得是使…

Problem C: 類的初體驗(III)

Description 定義一個類Data&#xff0c;只有一個double類型的屬性和如下4個方法&#xff1a; 1. 缺省構造函數&#xff0c;將屬性初始化為0&#xff0c;并輸出“Initialize a data 0”。 2. 帶參構造函數&#xff0c;將屬性初始化為指定參數&#xff0c;并輸出“Initialize…

Nginx- 實現跨域訪問

一、什么是跨域 跨域&#xff1a;由于瀏覽器的同源策略&#xff0c;即屬于不同域的頁面之間不能相互訪問各自的頁面內容。詳細見下表&#xff1a; 注&#xff1a;同源策略&#xff0c;單說來就是同協議&#xff0c;同域名&#xff0c;同端口 URL說明是否允許通信http://www.a…