AspNetCore(Kestrel)请求超时

7
我有以下设置:在 AWS 应用程序负载均衡器后面,运行着几个 Linux 容器上的 Web API(构建于 aspnetcore 2.0.5)。
客户端使用 HttpClient 向此 API 发出请求。该客户端在多个并行任务中运行调用。如果并行任务数量增加,则 API 开始抛出带有“请求超时”的异常消息。
调用栈如下:
at Microsoft.AspNetCore.Server.Kestrel.Internal.System.IO.Pipelines.PipeCompletion.ThrowFailed() at Microsoft.AspNetCore.Server.Kestrel.Internal.System.IO.Pipelines.Pipe.GetResult(ReadResult& result) at Microsoft.AspNetCore.Server.Kestrel.Internal.System.IO.Pipelines.Pipe.Microsoft.AspNetCore.Server.Kestrel.Internal.System.IO.Pipelines.IReadableBufferAwaiter.GetResult() at Microsoft.AspNetCore.Server.Kestrel.Internal.System.IO.Pipelines.ReadableBufferAwaitable.GetResult() at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.MessageBody.d__24.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Frame`1.d__2.MoveNext()
是什么原因导致了这个错误?是谁设置了超时时间,我应该如何进一步调查?
编辑:如果我尝试使用 Fiddler 捕获失败的请求,就不会再抛出错误了(可能是因为 Fiddler 以较低的并行度打开连接)。

你尝试过增加 httpClient.TimeOut 吗?此外,您是否在特定的端点或所有类型的请求中都遇到了这个问题? - Set
我尝试了httpClient.Timeout的不同设置(以及关闭或保持连接打开的组合),但没有任何差别。失败的方法正在执行一些漫长的文件系统操作。我创建了另一个方法,只是等待一段时间(使用await Task.Delay()),这个方法就不会抛出相同的错误。 - mslliviu
这些文件系统操作需要多长时间?如果超过几秒钟,那么这是一个设计缺陷。不应该由您的 Web 服务器处理冗长的操作,您应该启动某种类型的后台任务--在数据库中放置标志、将消息放入队列、启动 Web 作业(因为您在 Azure 上)等。如果持续时间少于5分钟,我个人会设置一个触发函数的队列,并利用 Function 应用程序的廉价自动缩放消耗计划。 - McGuireV10
哎呀,我想AWS是亚马逊,不是Azure。不过基本概念还是一样的。 - McGuireV10
啊,好的。你确认了客户端发出的所有调用都能到达主机吗?是什么类型的客户端发起这些调用?我在想,也许你遇到了并发连接限制(但如果客户端是.NET Core,那可能不会有限制,因为在Core中,默认值是int.MaxValue)。 - McGuireV10
显示剩余4条评论
1个回答

0

可能的原因之一是由于I/O绑定操作,您正在阻塞asp.net线程。从问题描述来看,似乎您的服务器处理请求到某个点。超过这个点它就无法处理了。

我认为如果您正确使用Async/Await,则可以服务更多并发请求而不受当前限制。

还要检查一下,通过配置是否可以增加Asp.Net线程数。传统的Asp.Net支持此功能。不确定Asp.Net Core是否具有此功能。

最后,由于您正在云中运行,请检查升级服务器配置的可行性。升级配置可能会帮助您提供更多的请求。显然,这应该是最后的选择。首先专注于改善现有硬件的应用程序性能。


我在整个API中使用异步/等待模式。我尝试调整线程计数(现在这是在libuv选项中设置的),但没有任何区别。我将升级机器到更强大的设备,以查看其影响。我会回来提供详细信息。 - mslliviu
似乎与线程数量有关。仅升级服务器没有改善。我通过将ThreadPool.MinThreads设置为更高的值(在我的情况下为800),并升级容器上的“nofile”限制(为Linux)来提高性能。我不确定,但希望这是导致请求超时消息的问题所在。 - mslliviu
最小线程不足 https://blogs.msdn.microsoft.com/vancem/2018/10/16/diagnosing-net-core-threadpool-starvation-with-perfview-why-my-service-is-not-saturating-all-cores-or-seems-to-stall/ 你解决了这个问题吗? - xSx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接