线程饥饿导致性能下降
线上反馈signalR推送有延期
CPU 和 内存 都是 90% 左右,由于经费的问题,让我们先尝试优化代码。
看了一下核心代码设置了信号量为50,限制速度。果断增大为100。
生产环境更新后,一点作用都没有,高峰期还是有延期,作用不大。
最后发现当前服务器有有一个报表服务,下午跑报表抢占了线程资源,导致signalR服务处理慢。只能在signalR服务 的 ThreadPool.SetMinThreads 设置线程池中最小的工作线程数和异步 I/O 线程数,优先保证当前服务的运行
总结
.NET 线程饥饿(Thread Starvation)是指程序在没有足够的资源来满足所有线程请求时,某些线程无法获取所需的资源并处于阻塞状态,从而导致整个程序的吞吐量下降、响应时间变慢的现象。
.NET 中常见的线程饥饿包括:
-
CPU 饥饿:当程序中存在大量密集型计算任务时,如果线程池中的工作线程数不足,这些计算任务就会争夺 CPU 资源,而其他线程则无法得到充分利用,从而导致线程饥饿。
-
I/O 饥饿:当程序中存在大量 I/O 操作时,如果线程池中的异步 I/O 线程数不足,这些 I/O 操作就会阻塞等待异步 I/O 线程的空闲,而其他线程则无法得到充分利用,从而导致线程饥饿。
-
线程池饥饿:当程序中存在大量短时任务时,如果线程池中的工作线程数太少,这些任务就会形成队列等待执行,而其他线程也无法得到充分利用,从而导致线程饥饿。
避免线程饥饿的方法包括:
-
增加系统资源:增加 CPU、内存等硬件资源,以满足程序对资源的需求。
-
调整线程池参数:根据实际情况调整线程池中工作线程数和异步 I/O 线程数等参数,以提高系统的并发处理能力。
-
使用异步编程模型:通过使用异步编程模型和异步 I/O 操作,可以避免阻塞和等待,从而提高程序的并发性和响应能力。
-
优化代码逻辑:通过优化代码逻辑和算法,尽可能减少单个线程占用资源的时间和数量,从而提高整个程序的吞吐量和性能。