环境:
window server 2016
.net core 2.1
大概并发在 50 个时会发生这个异常:
Reading the request body timed out due to data arriving too slowly. See MinRequestBodyDataRate.
哪位朋友遇到过?
去看了 KestrelHttpServer 源码。启动时 增加
.UseKestrel(opt =>
{
opt.Limits.MinRequestBodyDataRate = null;
})
问题得以解决。
你是怎么读取 Request.Body 的?
读取 Request.Body 是框架自己做的,我没有特殊处理 ,就是 controller 里 public void post([FormBody] JObject data){ ... }
1.检查服务器或者网络设备上行速度是否有限制,导致请求来不及处理。
2.提高线程池的线程数量,包括最大和最小。
嗯,我的并发 50+ 时就会出现。请问怎么“提高线程池的线程数量,包括最大和最小”?
@Skyzi:
System.Threading.ThreadPool.SetMaxThreads(600, 800);
不见得是这个问题导致的,先试试吧
@czd890: 确实不是这个原因。我的代码特殊的地方就是,我的请求进来后,我是先挂起的,把请求的数据分发的一个队列里,起另一个线程去处理数据,最后处理完成后再 Response、取消挂起。代码大概如下图:
@Skyzi: 估计是这个问题了。。。这什么特殊业务,非得这么玩。。。
@czd890: 这样的业务一般会写异步通知的方式,我不想用,所以才这么写,对 .net core 不熟悉,也是无头绪,下面是异常信息:
2018-08-23 21:03:32.7035|500|ERROR|Global Exception Logger|Reading the request body timed out due to data arriving too slowly. See MinRequestBodyDataRate. Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException: Reading the request body timed out due to data arriving too slowly. See MinRequestBodyDataRate.
at Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException.Throw(RequestRejectionReason reason)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Http1MessageBody.PumpAsync()
at System.IO.Pipelines.PipeCompletion.ThrowLatchedException()
at System.IO.Pipelines.Pipe.GetReadResult(ReadResult& result)
at System.IO.Pipelines.Pipe.GetReadAsyncResult()
at System.IO.Pipelines.Pipe.DefaultPipeReader.GetResult(Int16 token)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.MessageBody.ReadAsync(Memory`1 buffer, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpRequestStream.ReadAsyncInternal(Memory`1 buffer, CancellationToken cancellationToken)
at System.IO.StreamReader.ReadBufferAsync()
at System.IO.StreamReader.ReadToEndAsyncInternal()
at ImageRecognition.Controllers.ImageController.Post()
at lambda_method(Closure , Object )
at Microsoft.Extensions.Internal.ObjectMethodExecutorAwaitable.Awaiter.GetResult()
at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.AwaitableResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at System.Threading.Tasks.ValueTask`1.get_Result()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)
@Skyzi: 可能的原因是手动吧io线程挂起导致的。改成大约下面这样子试试看
Post(){
var data=...;
var res=await Task.Run(()=>{
//async process request
return res_data;
});
this.writeresponse(res);
}
@czd890: 最后去看 KestrelHttpServer 源码了。启动时 增加
.UseKestrel(opt =>
{
opt.Limits.MinRequestBodyDataRate = null;
})
就没有问题了。谢谢你的解答。