对外暴露有限的 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 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
五, 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
来源: https://www.cnblogs.com/tianqing/p/12764404.html