什么是Kestrel?
Kestrel 是一个跨平台的Web服务器,会默认在ASP.NET Core 项目模板中对其进行配置。未使用 IIS 托管时,ASP.NET Core 项目模板默认使用 Kestrel。
Kestrel 的功能包括:
在下面的模板生成的?Program.cs
?中,WebApplication.CreateBuilder?方法在内部调用?UseKestrel:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();
ASP.NET Core 项目配置为绑定到 5000-5300 之间的随机 HTTP 端口和 7000-7300 之间的随机 HTTPS 端口。 所选端口存储在生成的?Properties/launchSettings.json
?文件中,开发人员可以对其进行修改。?launchSetting.json
?文件仅用于本地开发。
如果没有终结点配置,则 Kestrel 绑定到?http://localhost:5000
。
Kestrel 可以从?IConfiguration?实例加载终结点。 默认情况下,Kestrel 配置从?Kestrel
?部分加载,终结点在?Kestrel:Endpoints
?中配置:
{
"Kestrel": {
"Endpoints": {
"MyHttpEndpoint": {
"Url": "http://localhost:8080"
}
}
}
}
上面的示例:
appsettings.json
?作为配置源。 但是,可以使用任何?IConfiguration
?源。MyHttpEndpoint
?的终结点。KestrelServerOptions?提供用于在代码中配置终结点的方法:
如果同时使用?Listen
?和?UseUrls?API,Listen
?终结点将覆盖?UseUrls
?终结点。
Listen、ListenLocalhost?和?ListenAnyIP?方法绑定到 TCP 套接字:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.Listen(IPAddress.Loopback, 5000);
serverOptions.Listen(IPAddress.Loopback, 5001, listenOptions =>
{
listenOptions.UseHttps("testCert.pfx", "testPassword");
});
});
上面的示例:
在 Windows 上,可以使用?New-SelfSignedCertificate?PowerShell cmdlet?创建自签名证书。 有关不受支持的示例,请参阅?UpdateIISExpressSSLForChrome.ps1。
在 macOS、Linux 和 Windows 上,可以使用?OpenSSL?创建证书。
Kestrel 支持使用 HTTPS 保护终结点。 通过 HTTPS 发送的数据使用传输层安全性 (TLS)?进行加密,以提高在客户端和服务器之间传输的数据的安全性。
HTTPS 需要 TLS 证书。 TLS 证书存储在服务器上,并将 Kestrel 配置为使用该证书。 应用可以在本地开发环境中使用?ASP.NET Core HTTPS 开发证书。 开发证书未安装在非开发环境中。 在生产环境中,必须显式配置 TLS 证书。 至少必须提供默认证书。
配置 HTTPS 和 TLS 证书的方式取决于终结点的配置方式:
Kestrel 可以使用默认 HTTPS 应用设置配置架构。 从磁盘上的文件或从证书存储中配置多个终结点,包括要使用的 URL 和证书。
任何未指定证书的 HTTPS 终结点(下例中的?HttpsDefaultCert
)会回退至在?Certificates:Default
?下定义的证书或开发证书。
以下示例适用于?appsettings.json
,但可以使用任何配置源:
{
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://localhost:5000"
},
"HttpsDefaultCert": {
"Url": "https://localhost:5004"
}
}
}
}
上面已经介绍过,使用?Listen
?API 时,ListenOptions?上的?UseHttps?扩展方法可用于配置 HTTPS。
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.Listen(IPAddress.Loopback, 5000);
serverOptions.Listen(IPAddress.Loopback, 5001, listenOptions =>
{
listenOptions.UseHttps("testCert.pfx", "testPassword");
});
});
ListenOptions.UseHttps
?参数:
filename
?是证书文件的路径和文件名,关联包含应用内容文件的目录。password
?是访问 X.509 证书数据所需的密码。configureOptions
?是配置?HttpsConnectionAdapterOptions
?的?Action
。 返回?ListenOptions
。storeName
?是从中加载证书的证书存储。subject
?是证书的主题名称。allowInvalid
?指示是否存在需要留意的无效证书,例如自签名证书。location
?是从中加载证书的存储位置。serverCertificate
?是 X.509 证书。有关?UseHttps
?重载的完整列表,请参阅?UseHttps。
上面介绍过,要配置 Kestrel 配置选项,可以在?Program.cs
?中调用?ConfigureKestrel:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
// ...
});
还可以从?appsettings.json
?或?appsettings.{Environment}.json
?文件配置?Kestrel :
{
"Kestrel": {
"Limits": {
"MaxConcurrentConnections": 100,
"MaxConcurrentUpgradedConnections": 100
},
"DisableStringReuse": true
}
}
KeepAliveTimeout?获取或设置保持活动状态超时:
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(2);
});
将调试器附加到 Kestrel 进程时,不会强制实施此超时限制。
MaxConcurrentConnections?获取或设置最大打开的连接数:
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.MaxConcurrentConnections = 100;
});
MaxConcurrentUpgradedConnections?获取或设置最大打开、升级的连接数:
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.MaxConcurrentUpgradedConnections = 100;
});
升级的连接是已从 HTTP 切换到另一个协议(如 WebSocket)的连接。 连接升级后,不会计入?MaxConcurrentConnections
?限制。
MaxRequestBodySize?获取或设置允许的请求正文的最大大小(以字节为单位)。
以下示例为所有请求配置?MaxRequestBodySize
:
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.MaxRequestBodySize = 100_000_000;
});
在 ASP.NET Core MVC 应用中替代限制的推荐方法是在操作方法上使用?RequestSizeLimitAttribute?属性:
[RequestSizeLimit(100_000_000)]
public IActionResult Get()
以下示例在一个自定义中间件中使用?IHttpMaxRequestBodySizeFeature?为特定请求配置?MaxRequestBodySize
:
app.Use(async (context, next) =>
{
var httpMaxRequestBodySizeFeature = context.Features.Get<IHttpMaxRequestBodySizeFeature>();
if (httpMaxRequestBodySizeFeature is not null)
httpMaxRequestBodySizeFeature.MaxRequestBodySize = 10 * 1024;
// ...
await next(context);
});
如果应用在开始读取请求后尝试配置请求的限制,则会引发异常。 使用?IHttpMaxRequestBodySizeFeature.IsReadOnly?属性检查设置?MaxRequestBodySize
?属性是否安全。
Kestrel 每秒检查一次数据是否以指定的速率(字节/秒)传入。 如果速率低于最小值,则连接超时。宽限期是 Kestrel 允许客户端将其发送速率提升到最小值的时间量。 在此期间不会检查速率。 宽限期有助于避免最初由于 TCP 慢启动而以较慢速率发送数据的连接中断。 最小速率也适用于响应。
MinRequestBodyDataRate?获取或设置请求正文的最小数据速率(以字节/秒为单位)。?MinResponseDataRate?获取或设置响应最小数据速率(以字节/秒为单位)。
以下示例为所有请求配置?MinRequestBodyDataRate
?和?MinResponseDataRate
:
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.MinRequestBodyDataRate = new MinDataRate(
bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
serverOptions.Limits.MinResponseDataRate = new MinDataRate(
bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
});
RequestHeadersTimeout?获取或设置服务器接收请求头所需的最大时间量:
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.RequestHeadersTimeout = TimeSpan.FromMinutes(1);
});
该部分中的限制在?KestrelServerLimits.Http2?上设置。
MaxStreamsPerConnection?限制每个 HTTP/2 连接的并发请求流的数量。 拒绝过多的流:
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.Http2.MaxStreamsPerConnection = 100;
});
HeaderTableSize?限制了服务器上 HPACK 编码器与解码器可以使用的标头压缩表的大小(以八进制数表示)。 HPACK 解码器为 HTTP/2 连接解压缩 HTTP 标头:
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.Http2.HeaderTableSize = 4096;
});
MaxFrameSize?指示允许接收的最大帧有效负载的大小(以八进制数表示):
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.Http2.MaxFrameSize = 16_384;
});
MaxRequestHeaderFieldSize?指示请求头字段序列的最大允许大小。 此限制适用于名称和值序列的压缩和未压缩表示形式:
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.Http2.MaxRequestHeaderFieldSize = 8192;
});
InitialConnectionWindowSize?表示服务器一次愿意接收和缓冲多少请求正文数据,这些数据在每个连接的所有请求(流)中汇总:
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.Http2.InitialConnectionWindowSize = 131_072;
});
请求也受?InitialStreamWindowSize?限制。
InitialStreamWindowSize?表示服务器愿意为每个流一次接收和缓冲多少请求正文数据:
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.Http2.InitialStreamWindowSize = 98_304;
});
请求也受?InitialConnectionWindowSize?限制。