Nguon: Microsoft Learn · .NET 8.0

Cấu hình Options cho Kestrel web server trong ASP.NET Core

Nguồn: Configure options for the ASP.NET Core Kestrel web server

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:

csharp
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:

csharp
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:

csharp
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:

csharp
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:

csharp
[RequestSizeLimit(100_000_000)]
public IActionResult Get()

Ví dụ sau cấu hình MaxRequestBodySize cho tất cả requests:

csharp
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:

csharp
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 MinRequestBodyDataRateMinResponseDataRate cho tất cả requests:

csharp
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 IHttpMinRequestBodyDataRateFeatureIHttpMinResponseDataRateFeature trong custom middleware:

csharp
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:

csharp
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:

csharp
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:

csharp
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:

csharp
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:

csharp
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:

csharp
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:

csharp
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:

Có hai tùy chọn cấu hình liên quan đến HTTP/2 keep alive pings:

csharp
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.

csharp
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: