Cấu hình Options cho Kestrel web server trong ASP.NET Core
Kestrel web server có các tùy chọn cấu hình ràng buộc đặc biệt hữu ích cho các triển khai đối mặt với Internet. Để cấu hình options của Kestrel, gọi ConfigureKestrel trong Program.cs:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
// ...
});Thiết lập các ràng buộc trên thuộc tính KestrelServerOptions.Limits. Thuộc tính này chứa instance của class KestrelServerLimits.
Giới hạn chung
Keep-alive timeout
KeepAliveTimeout lấy hoặc đặt keep-alive timeout:
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(2);
});Timeout này không được thực thi khi có debugger đính kèm vào process Kestrel.
Số kết nối client tối đa
MaxConcurrentConnections lấy hoặc đặt số lượng kết nối đang mở tối đa:
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.MaxConcurrentConnections = 100;
});MaxConcurrentUpgradedConnections lấy hoặc đặt số lượng kết nối đang mở đã được nâng cấp tối đa:
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.MaxConcurrentUpgradedConnections = 100;
});Kết nối được nâng cấp là kết nối đã chuyển từ HTTP sang giao thức khác, ví dụ như WebSockets. Sau khi nâng cấp, kết nối không được tính vào giới hạn MaxConcurrentConnections.
Kích thước request body tối đa
MaxRequestBodySize lấy hoặc đặt kích thước tối đa cho phép của bất kỳ request body nào tính bằng bytes.
Cách tiếp cận được khuyến nghị để ghi đè giới hạn trong ứng dụng ASP.NET Core MVC là dùng attribute RequestSizeLimitAttribute trên action method:
[RequestSizeLimit(100_000_000)] public IActionResult Get()
Ví dụ sau cấu hình MaxRequestBodySize cho tất cả requests:
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.MaxRequestBodySize = 100_000_000;
});Ví dụ sau cấu hình MaxRequestBodySize cho một request cụ thể sử dụng IHttpMaxRequestBodySizeFeature trong custom middleware:
app.Use(async (context, next) =>
{
var httpMaxRequestBodySizeFeature = context.Features.Get<IHttpMaxRequestBodySizeFeature>();
if (httpMaxRequestBodySizeFeature is not null)
httpMaxRequestBodySizeFeature.MaxRequestBodySize = 10 * 1024;
await next(context);
});Nếu ứng dụng cố cấu hình giới hạn trên một request sau khi bắt đầu đọc request đó, một exception sẽ được ném. Dùng thuộc tính IHttpMaxRequestBodySizeFeature.IsReadOnly để kiểm tra xem có an toàn để đặt thuộc tính MaxRequestBodySize không.
Khi ứng dụng chạy out-of-process phía sau ASP.NET Core Module, IIS đặt giới hạn và giới hạn request body size của Kestrel bị vô hiệu.
Tốc độ dữ liệu request body tối thiểu
Kestrel kiểm tra mỗi giây xem dữ liệu có đến với tốc độ được chỉ định tính bằng bytes/giây không. Nếu tốc độ giảm xuống dưới mức tối thiểu, kết nối sẽ bị timeout. Khoảng thời gian ân hạn (grace period) là thời gian Kestrel cho phép client tăng tốc độ gửi lên mức tối thiểu; tốc độ không được kiểm tra trong thời gian đó. Grace period giúp tránh loại bỏ các kết nối ban đầu gửi dữ liệu chậm do TCP slow-start.
MinRequestBodyDataRate lấy hoặc đặt tốc độ dữ liệu tối thiểu của request body tính bằng bytes/giây. MinResponseDataRate lấy hoặc đặt tốc độ dữ liệu tối thiểu của response tính bằng bytes/giây.
Ví dụ cấu hình MinRequestBodyDataRate và MinResponseDataRate cho tất cả requests:
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));
});Ví dụ cấu hình cho một request cụ thể bằng IHttpMinRequestBodyDataRateFeature và IHttpMinResponseDataRateFeature trong custom middleware:
app.Use(async (context, next) =>
{
var httpMinRequestBodyDataRateFeature = context.Features
.Get<IHttpMinRequestBodyDataRateFeature>();
if (httpMinRequestBodyDataRateFeature is not null)
{
httpMinRequestBodyDataRateFeature.MinDataRate = new MinDataRate(
bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
}
var httpMinResponseDataRateFeature = context.Features
.Get<IHttpMinResponseDataRateFeature>();
if (httpMinResponseDataRateFeature is not null)
{
httpMinResponseDataRateFeature.MinDataRate = new MinDataRate(
bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
}
await next(context);
});IHttpMinResponseDataRateFeature không có trong HttpContext.Features cho các HTTP/2 request. Việc sửa đổi rate limits trên cơ sở per-request nhìn chung không được hỗ trợ cho HTTP/2 do giao thức hỗ trợ request multiplexing. Tuy nhiên, IHttpMinRequestBodyDataRateFeature vẫn có trong HttpContext.Features cho các HTTP/2 request, vì read rate limit có thể bị vô hiệu hoàn toàn trên cơ sở per-request bằng cách đặt MinDataRate thành null.
Các rate limit toàn server được cấu hình qua KestrelServerOptions.Limits vẫn áp dụng cho cả kết nối HTTP/1.x và HTTP/2.
Request headers timeout
RequestHeadersTimeout lấy hoặc đặt thời gian tối đa mà server dành để nhận request headers:
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.RequestHeadersTimeout = TimeSpan.FromMinutes(1);
});Timeout này không được thực thi khi có debugger đính kèm vào process Kestrel.
Giới hạn HTTP/2
Các giới hạn trong phần này được đặt trên KestrelServerLimits.Http2.
Số streams tối đa mỗi kết nối
MaxStreamsPerConnection giới hạn số lượng request streams đồng thời trên mỗi kết nối HTTP/2. Các streams vượt quá sẽ bị từ chối:
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.Http2.MaxStreamsPerConnection = 100;
});Kích thước header table
HeaderTableSize giới hạn kích thước của các bảng nén header, tính bằng octets, mà HPACK encoder và decoder trên server có thể sử dụng:
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.Http2.HeaderTableSize = 4096;
});Kích thước frame tối đa
MaxFrameSize chỉ định kích thước frame payload lớn nhất được phép nhận, tính bằng octets:
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.Http2.MaxFrameSize = 16_384;
});Kích thước request header tối đa
MaxRequestHeaderFieldSize chỉ định kích thước tối đa cho phép của một chuỗi request header field:
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.Http2.MaxRequestHeaderFieldSize = 8192;
});Kích thước connection window ban đầu
InitialConnectionWindowSize chỉ định lượng dữ liệu request body mà server sẵn sàng nhận và buffer tại một thời điểm, tổng hợp trên tất cả requests (streams) mỗi kết nối:
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.Http2.InitialConnectionWindowSize = 131_072;
});Requests cũng bị giới hạn bởi InitialStreamWindowSize.
Kích thước stream window ban đầu
InitialStreamWindowSize chỉ định lượng dữ liệu request body mà server sẵn sàng nhận và buffer tại một thời điểm mỗi stream:
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.Http2.InitialStreamWindowSize = 98_304;
});Requests cũng bị giới hạn bởi InitialConnectionWindowSize.
Cấu hình HTTP/2 keep alive ping
Kestrel có thể được cấu hình để gửi HTTP/2 pings đến các client kết nối. HTTP/2 pings phục vụ nhiều mục đích:
- Giữ các kết nối idle không bị đóng. Một số client và proxy server đóng các kết nối idle. HTTP/2 pings được coi như hoạt động trên kết nối.
- Đóng các kết nối không lành mạnh. Các kết nối mà client không phản hồi keep alive ping trong thời gian cấu hình sẽ bị server đóng.
Có hai tùy chọn cấu hình liên quan đến HTTP/2 keep alive pings:
KeepAlivePingDelaylàTimeSpancấu hình khoảng thời gian ping. Server gửi keep alive ping đến client nếu không nhận được bất kỳ frame nào trong khoảng thời gian này. Keep alive pings bị vô hiệu khi tùy chọn được đặt thànhTimeSpan.MaxValue.KeepAlivePingTimeoutlàTimeSpancấu hình ping timeout. Nếu server không nhận được bất kỳ frame nào trong timeout này, kết nối sẽ bị đóng. Keep alive timeout bị vô hiệu khi đặt thànhTimeSpan.MaxValue.
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.Http2.KeepAlivePingDelay = TimeSpan.FromSeconds(30);
serverOptions.Limits.Http2.KeepAlivePingTimeout = TimeSpan.FromMinutes(1);
});Các tùy chọn khác
Synchronous I/O
AllowSynchronousIO kiểm soát xem synchronous I/O có được phép cho request và response không:
Cảnh báo: Nhiều thao tác blocking synchronous I/O có thể dẫn đến thread pool starvation (cạn kiệt thread pool), khiến ứng dụng không phản hồi. Chỉ bật AllowSynchronousIO khi sử dụng thư viện không hỗ trợ asynchronous I/O.
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.AllowSynchronousIO = true;
});Để biết thêm về các tùy chọn và giới hạn Kestrel khác, xem:
Hành vi khi đính kèm debugger
Các timeout và rate limit sau đây không được thực thi khi có debugger đính kèm vào process Kestrel:
KestrelServerLimits.KeepAliveTimeoutKestrelServerLimits.RequestHeadersTimeoutKestrelServerLimits.MinRequestBodyDataRateKestrelServerLimits.MinResponseDataRateIConnectionTimeoutFeatureIHttpMinRequestBodyDataRateFeatureIHttpMinResponseDataRateFeature