Async-Await api性能瓶颈在DB .net5.0 web api



.net5.0 Web API
由于客户端广泛使用的API很少,因此整体性能正在恶化。因此,我们决定将这些选定的API转换为Async/Await,以减少IIS的负载。
在实现相同的功能后,我们在本地环境中获得了更好的性能,大约有100个并行请求(通过jMeter)。但是,当我们将负载增加到200个请求时,它就开始给出以下错误:
"在从池中获得连接之前,超时时间已经过去了。这可能是因为所有的池连接都在使用中,并且达到了最大池大小。

我们意识到我们并没有完全提高性能,但我们将瓶颈从IIS转移到了DB。
为了解决这个问题,我们尝试改变连接字符串(我的SQL Server)属性,即最大池大小,ConnectRetryCount, ConnectRetryInterval等,这绝对有效,并给了我们更好的结果,但一切都伴随着权衡。增加最大池大小将使用DB服务器资源。
另外,我们永远无法预测有多少并行请求会来到我们的API,也就是说,如果我的最大池大小是400,如果有450个并行请求到达,它仍然会崩溃。

我们确定了一些选项,如使用SemaphoreSlime,以限制到达DB的请求数量,而不会打开太多的连接,从而限制超时错误。但是这里我们不能充分利用api的异步特性。

是否有一个优化的解决方案,或者我们错过了什么?
另外,如果我们选择使用SemaphoreSlime,它的安全性如何?

IIS和Kestrel可以配置为限制最大连接数,那么为什么要使用自己自制的解决方案呢?

您可以通过增加连接超时而不是使用SemaphoreSlim来实现相同的目标。

如果你想增加你的应用程序的吞吐量,你应该开始优化你的查询,如果这还不够,你应该考虑增加数据库服务器的硬件资源。

如果您的最大池大小为400,并发请求到达450个,它不一定会中断。如果池中没有可用的连接,Connection.OpenAsync将等待,直到有可用的连接。因此,如果查询足够快,它就不会超时。

这里有两个可以提高系统性能的建议:

  1. 缩短工作时间,减少并行工作:

    • 使用本地完成工作的存储过程,而不是在api和db之间移动数据
    • 扩展数据库,
    • 优化查询<
    • 确认索引/gh>
    • 使用缓存
    • 等。
  2. 接受请求,但将它们放在队列中,并使队列的消费者批量处理它们,而不是逐个处理。

最新更新