介绍
.NET 8 引入了请求超时中间件,以便全局以及对每个终结点配置请求超时。 在 .NET 8 或更高版本上运行时,YARP 2.1 中也提供此功能。
默认值
默认情况下,请求不会有任何超时,除了用于清理空闲请求的 ActivityTimeout。 RequestTimeoutOptions 中指定的默认策略也适用于代理请求。
与 ActivityTimeout 交互
路由级别 Timeout 和群集级别 ActivityTimeout 都适用于代理请求。 了解交互方式对于正确配置超时非常重要:
ActivityTimeout 按分区中的每个
HttpRequest群集进行配置,默认值为 100 秒。 每当请求上存在活动时,此超时将重置。 活动包括接收响应标头或成功读取或写入请求、响应或流数据(如 gRPC 或 WebSocket)。 TCP 保持活动状态和 HTTP/2 协议的 ping 不会重置超时,但 WebSocket 的 ping 会重置超时。超时是按每个路由进行配置的,并指定请求完成所允许的总时间。
哪个超时优先?
这两个超时同时适用。 如果请求 处于空闲 状态(无活动),则会 ActivityTimeout 取消请求。 如果请求 处于活动状态 ,但总体耗时过长,则路由级别 Timeout 将取消请求。 实际上,对于空闲请求,超时较短的那个将会先生效。
例如:
-
Timeout路由时间为300 秒,默认值为ActivityTimeout100 秒:如果请求处于空闲状态,则在ActivityTimeout100 秒后将被取消,即使路由允许最多 300 秒。 -
Timeout路由为 60 秒,默认值为ActivityTimeout100 秒:如果请求尚未完成,则请求将在 60 秒后取消,而不考虑活动。
调试注意事项
这些超时之间的重要区别:
- 当调试器附加到进程时,路由级超时不适用,因此可以更轻松地调试长时间运行的请求。
- ActivityTimeout 始终适用,即使附加了调试器。
ActivityTimeout为了避免干扰调试或合法的长时间运行的请求,请在群集的HttpRequest部分中显式配置它:
{
"Clusters": {
"cluster1": {
"HttpRequest": {
"ActivityTimeout": "00:10:00"
},
"Destinations": {
"cluster1/destination1": {
"Address": "https://localhost:10001/"
}
}
}
}
}
配置
可以通过 RouteConfig 为每个路由指定超时和超时策略,并且可以从配置文件的 Routes 部分绑定超时和超时策略。 与其他路由属性一样,无需重启代理即可修改和重新加载此属性。 策略名称不区分大小写。
超时时间以 TimeSpan 格式(HH:MM:SS)指定。 在同一路由上同时指定 Timeout 和 TimeoutPolicy 无效,将导致配置被拒绝。
请注意,当调试器附加到进程时,请求超时不适用。
示例:
{
"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/"
}
}
}
}
}
}
超时策略和默认策略可以在服务集合中配置,并且可以按如下方式添加中间件:
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();
禁用超时
在路由的 disable 参数中指定值 TimeoutPolicy 意味着请求超时中间件不会对此路由应用超时。
WebSocket协议
初始 WebSocket 握手完成后,请求超时会被禁用。 但是, ActivityTimeout 确实适用于 WebSocket 请求。 客户端或服务器可以通过与代理通信来启用 WebSocket 保持连接活动,以防止连接变为空闲状态并触发 ActivityTimeout。