Nguon: Microsoft Learn · .NET 8.0

Timeout yêu cầu trong YARP (YARP Request Timeouts)

Nguồn: YARP Request Timeouts

Giới thiệu

.NET 8 đã giới thiệu Request Timeouts Middleware để cho phép cấu hình timeout (thời gian chờ) yêu cầu toàn cục cũng như theo từng endpoint. Chức năng này cũng có sẵn trong YARP 2.1 khi chạy trên .NET 8 trở lên.

Mặc định

Các yêu cầu không có bất kỳ timeout nào theo mặc định, ngoài ActivityTimeout (thời gian chờ hoạt động) được sử dụng để dọn dẹp các yêu cầu nhàn rỗi. Một policy mặc định được chỉ định trong RequestTimeoutOptions sẽ áp dụng cho các yêu cầu được proxy.

Tương tác với ActivityTimeout

Cả Timeout ở cấp route và ActivityTimeout ở cấp cluster đều áp dụng cho các yêu cầu được proxy. Hiểu cách chúng tương tác là quan trọng để cấu hình timeout phù hợp:

Timeout nào được ưu tiên?

Cả hai timeout đều được áp dụng đồng thời. Nếu yêu cầu nhàn rỗi (không có hoạt động), ActivityTimeout sẽ hủy nó. Nếu yêu cầu đang hoạt động nhưng mất quá nhiều thời gian tổng thể, Timeout ở cấp route sẽ hủy nó. Trong thực tế, với một yêu cầu nhàn rỗi, timeout nào thấp hơn sẽ có hiệu lực trước.

Ví dụ:

Lưu ý khi debug

Một sự khác biệt quan trọng giữa hai timeout này:

Để tránh ActivityTimeout ảnh hưởng đến việc debug hoặc các yêu cầu chạy dài hợp lệ, hãy cấu hình rõ ràng trong phần HttpRequest của cluster:

json
{
  "Clusters": {
    "cluster1": {
      "HttpRequest": {
        "ActivityTimeout": "00:10:00"
      },
      "Destinations": {
        "cluster1/destination1": {
          "Address": "https://localhost:10001/"
        }
      }
    }
  }
}

Cấu hình

Timeout và Timeout Policy có thể được chỉ định cho từng route thông qua RouteConfig và có thể được liên kết từ phần Routes của file cấu hình. Giống như các thuộc tính route khác, điều này có thể được sửa đổi và tải lại mà không cần khởi động lại proxy. Tên policy không phân biệt chữ hoa/thường.

Timeout được chỉ định theo định dạng TimeSpan (HH:MM:SS). Chỉ định cả Timeout lẫn TimeoutPolicy trên cùng một route là không hợp lệ và sẽ khiến cấu hình bị từ chối.

Lưu ý rằng timeout yêu cầu không áp dụng khi debugger được đính kèm vào tiến trình.

Ví dụ:

json
{
  "ReverseProxy": {
    "Routes": {
      "route1" : {
        "ClusterId": "cluster1",
        "TimeoutPolicy": "customPolicy",
        "Match": {
          "Hosts": [ "localhost" ]
        }
      }
      "route2" : {
        "ClusterId": "cluster1",
        "Timeout": "00:01:00",
        "Match": {
          "Hosts": [ "localhost2" ]
        }
      }
    },
    "Clusters": {
      "cluster1": {
        "Destinations": {
          "cluster1/destination1": {
            "Address": "https://localhost:10001/"
          }
        }
      }
    }
  }
}

Các timeout policy và policy mặc định có thể được cấu hình trong service collection (tập hợp dịch vụ) và middleware có thể được thêm vào như sau:

csharp
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddReverseProxy()
    .LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"));

builder.Services.AddRequestTimeouts(options =>
{
    options.AddPolicy("customPolicy", TimeSpan.FromSeconds(20));
});

var app = builder.Build();

app.UseRequestTimeouts();

app.MapReverseProxy();

app.Run();

Tắt timeout

Chỉ định giá trị disable trong tham số TimeoutPolicy của route có nghĩa là middleware timeout yêu cầu sẽ không áp dụng timeout cho route này.

WebSockets

Timeout yêu cầu bị tắt sau khi WebSocket handshake (bắt tay WebSocket) ban đầu. Tuy nhiên, ActivityTimeout áp dụng cho các yêu cầu WebSocket. WebSocket keep-alives có thể được bật bởi client hoặc server đang giao tiếp với proxy để giữ cho kết nối không bị nhàn rỗi và kích hoạt ActivityTimeout.