ASP.NET Core技術研究-全面認識Web伺服器Kestrel
因為IIS不支援跨平台的原因,我們在更新到ASP.NET Core後,會接觸到一個新的Web伺服器Kestrel。相信大家剛接觸這個Kestrel時,會有各種各樣的疑問。
今天我們全面認識一下ASP.NET Core的預設Web伺服器Kestrel。
一、初識Kestrel
首先,Kestrel是一個跨平台的Web伺服器,支援運作在Windows、macOS、Linux等作業系統中。Kestrel支援一下使用場景:
HTTPS
Opaque upgrade used to enable WebSockets(啟用WebSocket情況下的不透明更新)
Unix sockets for high performance behind Nginx(Nginx高性能模式下的Unix套接字)
HTTP2(不支援macOS)
Kestrel支援運作在所有.NET 支援的平台和版本之上。
二、Kestrel主要應用場景
Kestrel主要有兩種使用模式:
1. Kestrel直接作為Web伺服器,直接接收并處理各類Http請求:
2. 與各類反向代理伺服器(例如Nginx、Apache、IIS)配合使用,反向代理伺服器接收Http請求,将這些請求轉發到Kestrel Web伺服器
使用反向代理伺服器的好處有哪些呢?
對外暴露有限的HTTP服務
更加安全,反向代理伺服器做了一層過濾、防護和轉發
通過反向代理伺服器實作負載均衡和動态請求分發路由
減少域名使用,降低WAF防火牆防護成本
安全通信 (HTTPS) 配置,HTTPS轉HTTP,僅反向代理伺服器需要 X.509 證書,并且該伺服器可使用普通 HTTP 協定與内部網絡的應用伺服器通信。
三、Kestrel支援特性之-HTTP/2
Kestrel在以下作業系統和.NET Core版本下支援HTTP/2
作業系統:
Windows Server 2016/Windows 10 或更高版本
具有 OpenSSL 1.0.2 或更高版本的 Linux(例如,Ubuntu 16.04 或更高版本)
macOS 的未來版本将支援 HTTP/2
macOS 的未來版本将支援 †HTTP/2。 ‡Kestrel 在 Windows Server 2012 R2 和 Windows 8.1 上對 HTTP/2 的支援有限。
目标架構:.NET Core 2.2 或更高版本
關于HTTP/2 可以參考一下超連結:
https://http2.github.io/ 關于HTTP/2和HTTP/1.1的全方位對比,可以參考這個超連結: https://cheapsslsecurity.com/p/http2-vs-http1/四、在ASP.NET Core中使用Kestrel
在ASP.NET Core的架構Microsoft.AspNetCore.App内置了package:Microsoft.AspNetCore.Server.Kestrel ,即原生對Kestrel的支援:
大家可以找到ASP.NET Core 3.1的本地目錄:C:Program FilesdotnetpacksMicrosoft.AspNetCore.App.Ref3.1.0refnetcoreapp3.1 中找到Kestrel相關的dll:
當我們建立一個ASP.NET Core Project,在Program.cs類中有以下代碼,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup();
});
}
我們通過檢視ConfigureWebDefaults的實作源碼可以發現,在其内部調用了UseKestrel()方法,即ASP.NET Core預設使用Kestrel Web伺服器!
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
internal static void ConfigureWebDefaults(IWebHostBuilder builder)
{
builder.ConfigureAppConfiguration((ctx, cb) =>
{
if (ctx.HostingEnvironment.IsDevelopment())
{
StaticWebAssetsLoader.UseStaticWebAssets(ctx.HostingEnvironment, ctx.Configuration);
}
});
builder.UseKestrel((builderContext, options) =>
options.Configure(builderContext.Configuration.GetSection("Kestrel"));
})
.ConfigureServices((hostingContext, services) =>
// Fallback
services.PostConfigure(options =>
if (options.AllowedHosts == null || options.AllowedHosts.Count == 0)
{
// "AllowedHosts": "localhost;127.0.0.1;[::1]"
var hosts = hostingContext.Configuration["AllowedHosts"]?.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
// Fall back to "*" to disable.
options.AllowedHosts = (hosts?.Length > 0 ? hosts : new[] { "*" });
}
});
// Change notification
services.AddSingleton>(
new ConfigurationChangeTokenSource(hostingContext.Configuration));
services.AddTransient();
if (string.Equals("true", hostingContext.Configuration["ForwardedHeaders_Enabled"], StringComparison.OrdinalIgnoreCase))
services.Configure(options =>
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
// Only loopback proxies are allowed by default. Clear that restriction because forwarders are
// being enabled by explicit configuration.
options.KnownNetworks.Clear();
options.KnownProxies.Clear();
});
services.AddTransient();
services.AddRouting();
.UseIIS()
.UseIISIntegration();
}
以上詳細的代碼可以參考,上一篇博文:.NET Core技術研究-主機Host
五、Kestrel的配置選項
我們可以使用 webBuilder.ConfigureKestrel設定Kestrel的一些選項:
接下來,我們看一下Kestrel Web伺服器提供了哪些選項設定:
1. KeepAliveTimeout:保持活動會話逾時時間
預設2分鐘,可以用以下代碼進行設定:
serverOptions.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(2);
2. 用戶端最大連接配接數: MaxConcurrentConnections、 MaxConcurrentUpgradedConnections
預設情況下,最大連接配接數不受限制;
可以通過 MaxConcurrentConnections,設定整個應用設定并發打開的最大 TCP 連接配接數。
對于已從 HTTP 或 HTTPS 更新到另一個協定(例如,Websocket 請求)的連接配接,有一個單獨的限制MaxConcurrentUpgradedConnections。 連接配接更新後,不會計入 MaxConcurrentConnections 限制。
可以用以下代碼進行設定:
serverOptions.Limits.MaxConcurrentConnections = 100;
serverOptions.Limits.MaxConcurrentUpgradedConnections = 100;
3. 請求正文最大大小: MaxRequestBodySize
預設的請求正文最大大小為 30,000,000 位元組,大約 28.6 MB
serverOptions.Limits.MaxRequestBodySize = 10 * 1024;
在 ASP.NET Core MVC 應用中替代限制的推薦方法是在操作方法上使用 RequestSizeLimitAttribute 屬性:
[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()
4. 請求正文最小資料速率 MinRequestBodyDataRate MinResponseDataRate
Kestrel 每秒檢查一次資料是否以指定的速率(位元組/秒)傳入。 如果速率低于最小值,則連接配接逾時。
寬限期是 Kestrel 提供給用戶端用于将其發送速率提升到最小值的時間量;在此期間不會檢查速率。 寬限期可以盡可能地避免最初由于 TCP 慢啟動而以較慢速率發送資料的連接配接中斷。
預設的最小速率為 240 位元組/秒,包含 5 秒的寬限期。
最小速率也适用于HttpResponse響應。 除了屬性和接口名稱中具有 RequestBody 或 Response 以外,用于設定請求限制和響應限制的代碼相同。
serverOptions.Limits.MinRequestBodyDataRate = new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
serverOptions.Limits.MinResponseDataRate = new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
5. 請求Header逾時 RequestHeadersTimeout
擷取或設定伺服器接收請求标頭所花費的最大時間量。 預設值為 30 秒。
serverOptions.Limits.RequestHeadersTimeout = TimeSpan.FromMinutes(1);
6. 每個連接配接的最大的請求流的數量 MaxStreamsPerConnection
Http2.MaxStreamsPerConnection 限制每個 HTTP/2 連接配接的并發請求流的數量。 拒絕過多的流。
serverOptions.Limits.Http2.MaxStreamsPerConnection = 100;
7. 标題表大小
HPACK 解碼器解壓縮 HTTP/2 連接配接的 HTTP 标頭。 Http2.HeaderTableSize 限制 HPACK 解碼器使用的标頭壓縮表的大小。 該值以八位位元組提供,且必須大于零 (0)。
serverOptions.Limits.Http2.HeaderTableSize = 4096;
8. 最大幀大小 Http2.MaxFrameSize
Http2.MaxFrameSize 表示伺服器接收或發送的 HTTP/2 連接配接幀有效負載的最大允許大小。 該值以八位位元組提供,必須介于 2^14 (16,384) 和 2^24-1 (16,777,215) 之間。
serverOptions.Limits.Http2.MaxFrameSize = 16384;
- 最大請求頭大小 Http2.MaxRequestHeaderFieldSize
Http2.MaxRequestHeaderFieldSize 表示請求标頭值的允許的最大大小(用八進制表示)。 此限制适用于名稱和值的壓縮和未壓縮表示形式。 該值必須大于零 (0)。
serverOptions.Limits.Http2.MaxRequestHeaderFieldSize = 8192;
- 初始連接配接視窗大小 Http2.InitialConnectionWindowSize
Http2.InitialConnectionWindowSize 表示伺服器一次性緩存的最大請求主體資料大小(每次連接配接時在所有請求(流)中彙總,以位元組為機關)。 請求也受 Http2.InitialStreamWindowSize 限制。 該值必須大于或等于 65,535,并小于 2^31 (2,147,483,648)。
預設值為 128 KB (131,072)
serverOptions.Limits.Http2.InitialConnectionWindowSize = 131072;
11. 初始流視窗大小 Http2.InitialStreamWindowSize
Http2.InitialStreamWindowSize 表示伺服器針對每個請求(流)的一次性緩存的最大請求主體資料大小(以位元組為機關)。 請求也受 Http2.InitialConnectionWindowSize 限制。 該值必須大于或等于 65,535,并小于 2^31 (2,147,483,648)。
預設值為 96 KB (98,304)
serverOptions.Limits.Http2.InitialStreamWindowSize = 98304;
12. 同步IO AllowSynchronousIO
AllowSynchronousIO 控制是否允許對請求和響應使用同步 IO。 預設值為 false。這個設定需要注意一下:
大量的阻止同步 IO 操作可能會導緻線程池資源不足,進而導緻應用無響應。 僅在使用不支援異步 IO 的庫時,才啟用 AllowSynchronousIO。
serverOptions.AllowSynchronousIO = true;
以上是ASP.NET Core Web伺服器Kestrel的一些研究和梳理,分享給大家。
原文位址
https://www.cnblogs.com/tianqing/p/12764404.html