由於IIS不支持跨平臺的緣由,咱們在升級到ASP.NET Core後,會接觸到一個新的Web服務器Kestrel。相信你們剛接觸這個Kestrel時,會有各類各樣的疑問。html
今天咱們全面認識一下ASP.NET Core的默認Web服務器Kestrel。git
1、初識Kestrelgithub
首先,Kestrel是一個跨平臺的Web服務器,支持運行在Windows、macOS、Linux等操做系統中。Kestrel支持一下使用場景:web
3、Kestrel支持特性之-HTTP/2緩存
Kestrel在如下操做系統和.NET Core版本下支持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/ app
關於HTTP/2和HTTP/1.1的全方位對比,能夠參考這個超連接:https://cheapsslsecurity.com/p/http2-vs-http1/
4、在ASP.NET Core中使用Kestrel
在ASP.NET Core的框架Microsoft.AspNetCore.App內置了package:Microsoft.AspNetCore.Server.Kestrel ,即原生對Kestrel的支持:
你們能夠找到ASP.NET Core 3.1的本地目錄:C:\Program Files\dotnet\packs\Microsoft.AspNetCore.App.Ref\3.1.0\ref\netcoreapp3.1 中找到Kestrel相關的dll:
當咱們新建一個ASP.NET Core Project,在Program.cs類中有如下代碼,
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<Startup>(); }); }
咱們經過查看ConfigureWebDefaults的實現源碼能夠發現,在其內部調用了UseKestrel()方法,即ASP.NET Core默認使用Kestrel Web服務器!
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<HostFilteringOptions>(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<IOptionsChangeTokenSource<HostFilteringOptions>>( new ConfigurationChangeTokenSource<HostFilteringOptions>(hostingContext.Configuration)); services.AddTransient<IStartupFilter, HostFilteringStartupFilter>(); if (string.Equals("true", hostingContext.Configuration["ForwardedHeaders_Enabled"], StringComparison.OrdinalIgnoreCase)) { services.Configure<ForwardedHeadersOptions>(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<IStartupFilter, ForwardedHeadersStartupFilter>(); } services.AddRouting(); }) .UseIIS() .UseIISIntegration(); }
以上詳細的代碼能夠參考,上一篇博文:.NET Core技術研究-主機Host
5、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;
9. 最大請求頭大小 Http2.MaxRequestHeaderFieldSize
Http2.MaxRequestHeaderFieldSize
表示請求標頭值的容許的最大大小(用八進制表示)。 此限制適用於名稱和值的壓縮和未壓縮表示形式。 該值必須大於零 (0)。
serverOptions.Limits.Http2.MaxRequestHeaderFieldSize = 8192;
10. 初始鏈接窗口大小 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的一些研究和梳理,分享給你們。
周國慶
2020/4/24