Проблема особенно проявляется, когда под нагрузкой наши экземпляры начинают выдавать исключение:
Код: Выделить всё
Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException: Unexpected end of request content.
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Http1ContentLengthMessageBody.ReadAsyncInternal(CancellationToken cancellationToken)
at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpRequestStream.ReadAsyncInternal(Memory`1 destination, CancellationToken cancellationToken)
at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token)
at System.Text.Json.Serialization.ReadBufferState.ReadFromStreamAsync(Stream utf8Json, CancellationToken cancellationToken, Boolean fillBuffer)
at System.Text.Json.Serialization.Metadata.JsonTypeInfo`1.DeserializeAsync(Stream utf8Json, CancellationToken cancellationToken)
at System.Text.Json.Serialization.Metadata.JsonTypeInfo`1.DeserializeAsObjectAsync(Stream utf8Json, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonInputFormatter.ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonInputFormatter.ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
at Microsoft.AspNetCore.Mvc.ModelBinding.Binders.BodyModelBinder.BindModelAsync(ModelBindingContext bindingContext)
Я вижу в трассировка стека на самом деле вызывает методы с параметрами canceltoken, но мне интересно, есть ли проблема, из-за которой служба не учитывает отмену?
Я создал специальную оболочку вокруг BodyModelBinder и добавили к нему логику отмены ниже, и это уменьшило количество длительных запросов, и мы возвращаем клиенту ответ по тайм-ауту, но (из-за характера задач в .net) привязка модели все еще пытается завершиться в фоновом режиме, сохраняет использует ресурсы и в конечном итоге выходит из строя.
Мы используем .net8 на k8s 1.30, и перед этой службой стоит балансировщик нагрузки istio.
Я хотел спросить, есть ли лучший/правильный способ отменить запрос еще до того, как он достигнет контроллера?
Заранее спасибо,
Пользовательский код отмены:
Код: Выделить всё
public async Task BindModelAsync(ModelBindingContext bindingContext)
{
var token = CancellationTokenSource.CreateLinkedTokenSource(bindingContext.HttpContext.RequestAborted);
var task = _actualModelBinder.BindModelAsync(bindingContext);
var delay = Task.Delay(TimeSpan.FromSeconds(5), token.Token);
if (await Task.WhenAny(delay, task) == task)
{
// Task completed within timeout.
// Consider that the task may have faulted or been canceled.
// We re-await the task so that any exceptions/cancellation is rethrown.
token.Cancel();
await task;
}
else if (bindingContext.HttpContext.RequestAborted.IsCancellationRequested)
{
throw new OperationCanceledException("Request cancelled.");
}
else
{
throw new TimeoutException("Model binding timed out.");
}
}

Подробнее здесь: https://stackoverflow.com/questions/791 ... g-properly
Мобильная версия