调试 ASP.NET Core MVC 中令人讨厌的锁争用问题

问题描述 投票:0回答:1

我们正在处理 .NET 6 中高流量 ASP.NET Core MVC 应用程序中严重的锁争用问题,该应用程序在 IIS Windows Server 中作为进程内托管。

我们正在尝试启用一项功能,对内部服务进行 Http 调用,当我们启用该功能时,我们会发现锁争用增加(来自 dotnet-counters)、CPU 峰值(从 20% 到 100%)、峰值RAM(从 4GB 到 12GB)、线程池中线程数量的增加(从 ~60 到 ~310),显然应用程序很难满足传入的请求。 该问题仅出现在生产环境中,不幸的是我们无法在任何其他环境(本地、UAT、暂存)中重现该问题。

我们进行了无数的转储和跟踪来分析和识别问题,但是所有这些都指向一般的“锁争用增加”问题,并且热路径始终是此堆栈跟踪:

ntdll.dll!NtRemoveIoCompletion()             
KERNELBASE.dll!GetQueuedCompletionStatus()           
System.Private.CoreLib.dll!00007ff803838421()            
[Managed to Native Transition]
System.Private.CoreLib.dll!System.Threading.LowLevelLifoSemaphore.WaitForSignal(int timeoutMs = 0x00004e20)
System.Private.CoreLib.dll!System.Threading.LowLevelLifoSemaphore.Wait(int timeoutMs, bool spinWait)
System.Private.CoreLib.dll!System.Threading.PortableThreadPool.WorkerThread.WorkerThreadStart()
System.Private.CoreLib.dll!System.Threading.Thread.StartCallback()
[Native to Managed Transition]
kernel32.dll!BaseThreadInitThunk()
ntdll.dll!RtlUserThreadStart()           

实际上,我们看到前后转储中的线程数量大幅增加,所有线程都指向等待 GetQueuedCompletionStatus() 方法的 IOCP 线程。

不幸的是,我们无法识别产生 IOCP 线程的工作线程,并且我们不知道有任何方法将 IOCP 线程关联到 IOCP 端口和相关工作线程。

我们正在盲目地尝试进行与异步实现相关的更改,但仍然没有成功。

我们还尝试了所有 HttpClient 模式,只是为了确保我们没有遗漏一些明显的东西: 静态 HttpClient 寿命长 使用 IHttpClientFactory 的短暂命名 HttpClient 实例 长期存在的 HttpClient 实例的自定义池

我们已将最小工作线程和 iocp 线程设置为 200,然后从默认值设置为 300,但仍然没有运气或应用程序的行为发生任何变化。

运行syncblk不会显示任何内容(未检测到同步锁),也不会显示任何其他从转储或跟踪中识别锁/争用的常见方法。

我真的很感激任何对此的反馈,因为我们已经在墙上撞了一个多月了,谢谢! :)

c# asp.net-mvc httpclient iocp contention
1个回答
0
投票

这个问题有运气吗?遇到同样的问题,我猜测它与此ASP.Net Core Thread Starvation in high load

有关

尚未尝试链接上的解决方案。

© www.soinside.com 2019 - 2024. All rights reserved.