【发布时间】:2023-12-30 20:01:01
【问题描述】:
我们正在对.NET Core API 端点上的以下性能问题进行故障排除:
- 在较小的负载下,端点始终以小于
500MS的速度返回。 - 当我们从 3 个浏览器访问端点时,每秒一个请求,它逐渐变慢(在添加第三个浏览器进行调用的一分钟内,响应时间下降到
50,000MS或更糟. - 每个额外的浏览器添加 API 使用的线程,例如40 个线程基础,第二个浏览器访问端点导致 52 个线程,第三个峰值达到 70 个,依此类推。
- 当加载一个端点时,整个 API 会缓慢返回(所有端点)。这是我与第 3 点一起思考“线程耗尽”的主要原因。
目前的代码如下所示:
public IActionResult GetPresentationByEvent(int eventid)
{
return Authorized(authDto =>
{
var eventList = _eventService.GetPresentationByEvent(eventid);
return Ok(eventList)
})
}
我的理论是return Authorized(authDto => 持有一个线程直到它返回,导致线程耗尽。
public async Task<IActionResult> GetPresentationByEvent(int eventid)
{
return Authorized(async authDto =>
{
Task<List<whatever>> eventList = _eventService.GetPresentationByEvent(eventid);
return Ok(eventList)
}
}
Authorized 是第三方库的一部分,所以我不能轻易测试。想知道这是否是一个可能的问题/解决方案。
【问题讨论】:
-
这只有在调用一直是异步的情况下才有效,例如直到数据库/文件访问。见blog.stephencleary.com/2013/11/there-is-no-thread.html
-
“第三次飙升至 70”非常奇怪。那些线程在做什么?预热后你应该有一个基本的线程数,之后的每个并发请求应该只增加一个线程。
-
我现在正在调查。我更改了调用以返回一个新列表,而无需去 db / 执行任何身份验证。每个浏览器也建立了一个 SignalR 连接,所以也许我正在那里启动线程并且端点变慢只是一个副作用。现在将进行测试。 Ty 的回复,他们真的在帮助我思考这个问题。
-
@StephenCleary 让我纠正一下自己 - 每个浏览器都在运行一个负载测试功能,它每秒向 API 发出一个请求。所以,从这个角度来看,我认为线程的数量是有意义的。附言- 它不是 signalR,在没有到达此端点的情况下建立了 SignalR 连接,并且端点/整个 API 响应良好。现在更加迷失了,因为让端点返回一个空列表仍然无法处理每秒 3 个请求(来自 3 个浏览器)。
标签: c# multithreading asp.net-core-2.1 non-exhaustive-patterns