BLOCKED_TIME
通常意味着线程根本没有做任何事情的时期。这可能是 I/O 周期,其中涉及网络或其他类型的延迟,或者花费在等待锁上的时间,例如在信号量的情况下。简而言之,这并不一定能告诉你任何事情,因为线程空闲有完全标准和合理的理由。但是,阻塞所花费的大量时间可能表明存在潜在问题。也许你有太多的网络延迟。也许您正试图在慢速驱动器上做太多的文件系统工作。简而言之,它可能表示存在问题,也可能不表示存在问题,即使它确实表示存在问题,也不能真正告诉您问题所在。
一般来说,如果您遇到线程饥饿,您首先应该查看的是线程池利用率。您是否在任何地方都使用异步?您是否在做一些 Web 应用程序中的大禁忌,例如使用Task.Run
,Task.StartNew
或者更糟,Thread.Start
?所有这些创建的线程都来自同一个线程池,因此会成比例地降低您的服务器吞吐量。
尝试通过将长时间运行的作业改组到新线程来安排长时间运行的作业是一种非常常见的模式。这对 Web 应用程序来说是致命的。池中的所有线程都用于服务请求,而不是长时间运行的作业,因此,应快速有效地处理请求,以便线程可以在短时间内返回池以处理其他请求。如果您需要后台工作,则需要通过完全卸载到另一个进程甚至另一台机器来真正将其后台运行。
除此之外,也许您只是获得了超出服务器通常可以处理的负载。这总是一种可能。也许您需要垂直扩展您的系统资源(以及与之相关的线程池)。也许您需要通过在前面复制此服务器并使用负载均衡器来进行水平扩展。鉴于您在同一台服务器上运行多个不同的东西,一个简单的水平扩展方法是将这些东西简单地分配给他们自己的机器。仅此一项可能会有很大帮助。但是,垂直或水平缩放应该是您最后的手段。确保您首先有效地使用资源,然后再将更多资源投入到低效的事情上。