Тайм-аут чтения тела запроса истек из-за слишком поступления данных медленно. См. MinRequestBodyDataRate
В производственной среде запросы обычно представляют собой смесь быстрых и медленных мобильных соединений.
I удалось воспроизвести эти ошибки в тестовой среде, используя умеренную нагрузку (максимум 6 одновременных запросов) медленных соединений путем регулирования скорости запроса Jmeter до 2048 байт/с (что само по себе не должно быть достаточно низким, чтобы вызвать MinbodyDataRate 240 Б/с). настройка Kestrel)
Исключение возникает в пользовательском классе TextInputFormatter при вызове JArray.Load:
Код: Выделить всё
public override Task ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
{
var stream = context.HttpContext.Request.Body;
using (var reader = context.ReaderFactory(stream, encoding))
using (var jsonReader = new JsonTextReader(reader))
{
// Don't close the request stream because you many need it in other middleware or controllers.
jsonReader.CloseInput = false;
bool isSuccessful = true;
List model = null;
try
{
Assembly assembly = typeof(BaseCommand).Assembly;
// here we're reading and parsing the json array directly from the stream
var objCollection = JArray.Load(jsonReader);
Log.Information("Json message:{0}", JsonConvert.SerializeObject(objCollection));
model = objCollection
.Select((obj) =>
{
// here some code mapping the incoming data to the internal type BaseCommand
// ...
return mappedCmd;
}).ToList();
}
catch (Exception ex)
{
Log.Error(ex, "Error parsing BaseCommand");
isSuccessful = false;
}
if (isSuccessful)
{
if (model == null && !context.TreatEmptyInputAsDefaultValue)
return InputFormatterResult.NoValueAsync();
else
return InputFormatterResult.SuccessAsync(model);
}
return InputFormatterResult.FailureAsync();
}
}
Если я проведу тот же тест Jmeter без регулирования, количество активных запросов на сервере останется около 1, и у нас не будет ошибок.
После прочтения этой темы Я заподозрил нехватку потока и поэтому асинхронизировал метод (используя await JArray.LoadAsync() вместо JArray.Load( )), а также увеличил номер MinThread пула потоков (10 вместо 1): Вопреки моим ожиданиям, это не дало никакого эффекта !
Я проверил диагностику ЦП и памяти, и они не перегружены: никогда не превышает 15% ЦП и 10% памяти.
API в настоящее время размещен в контейнере докеров Linux с использованием linux (alpine).
Я упускаю, что мой код снижает производительность API, или мне следует просто ограничить количество входящих запросов, чтобы избежать этой ошибки?
Подробнее здесь: https://stackoverflow.com/questions/790 ... tformatter
Мобильная версия