什么是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();
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 限制。