TL;DR; 为工作进程提供更多线程!
背景
我们有一个 ASP.NET 应用程序,它公开一个 Web API,其中一个“端点/方法”向外部系统(SQL、AD 等)发出一组查询,大约需要 4 秒。
IO 调用是同步的,因此请求线程被阻塞直到一切完成。
该应用程序是用 .NET 4.6.2 编写的,并在 IIS 7.5 上运行
问题
我们遇到了负载非常大的现象,在短时间内向端点发出了 100 个请求,这似乎导致了“线程饥饿”,请求因此排队。这导致应用程序其余部分的响应时间不可接受。
在负载爆发期间,服务器上的 CPU 和内存都很好。SQL 和 AD 都很好(即它们可以毫无问题地响应来自其他应用程序的其他请求)
可能的解决方案
我的目标是为工作进程提供更多线程,但似乎找不到正确的配置。
使用生成的machine.config:
<processModel autoConfig="false" maxWorkerThreads="200" maxIoThreads="200" minWorkerThreads="100"/>
<httpRuntime minFreeThreads="704" minLocalRequestFreeThreads="608"/>
但与使用默认值相比,它似乎产生的结果很小甚至没有结果。
我遗漏了什么吗?
答案1
我们遇到了类似的问题,我们通过增加工作进程而不是线程数量解决了这个问题。我们有 5 个 Web 应用程序,全部托管 ASP.NET REST API,每个应用程序都分配有单独的 AppPool。然而,我们仍然面临着由单个 AppPool 上运行的缓慢数据库/IO 调用产生的峰值。
然后,我们开始寻找如何增加工作进程,以及这是否有助于缓解请求阻塞。我们发现这篇文章很有帮助。https://medium.com/@sanjay.rajak/does-api-response-fast-if-maximum-worker-processes-is-more-than-1-4b877af6b951
我们没有改变任何其他东西,没有改变 AppPools 的 CPU 或内存设置,但应用程序性能仍然在非常低的排队情况下好得多。
VM 中的虚拟核心数 = 6 最大工作进程数 = 3
检查这是否有效。