我有 ASP.NET 应用程序(框架 4.8),它偶尔会在几毫秒的时间内达到 100% 的 CPU 使用率。重要的是要知道,在这样的 CPU 负载期间或之前,应用程序不会遇到客户端 RPS 爆发。它实际上只是在 CPU 使用率激增之前服务于几个客户端请求。
查看带有 WPA 图表的 perfview 转储CPU Usage (Sampled)
,我看到 CPU 峰值的顶部以及峰值的幻灯片都充满了 CPU 样本Dequeue
和TrySteal
方法。系统指标还显示,在 CPU 负载期间,应用程序经历了使用的工作线程 ( ThreadPool.GetAvailableThreads - ThreadPool.GetMinThreads
) 的爆发,我设置为ThreadPool.SetMinThreads
. 机器有 16 个核心,所以我测试了应用程序,每个核心的值为 2048 和 512 个工人:每个核心分别有 128 和 32 个工人。
就目前而言,看起来 CPU 负载是由大量工作线程引起的,试图在没有可用的情况下接收任何工作请求。因此工作人员浪费 CPU 试图在他们的本地队列、全局线程池队列中查找工作请求,并试图从其他线程的本地队列中窃取工作。
什么可能导致工作线程数量激增?16 个 CPU 内核真的会因为 512 名工人试图找工作而饿死,还是只是其他任何问题的结果?
附件说明
1) CPU 样本在所有应用线程堆栈中的分布
2) CPU 样本在单个随机应用程序线程堆栈中的分布