.NET執行緒池最大執行緒數的限制-記一次IIS併發瓶頸
.NET ThreadPool 最大執行緒數的限制
IIS併發瓶頸,有幾個地方,IIS執行緒池的最大佇列數,工作程序數,最大併發數。這些這裡就不展開。主要是最近因為過度使用Task 導致的執行緒數佔用過多,所以實驗了一下 .net執行緒池 的限制,分享一下。
注意IIS執行緒池與.NET執行緒池不是同一個東西,下面詳解。
W3 Thread Pool(W3TP)
當處於核心模式的http.sys接收到來自使用者的請求之後,會將請求放入佇列中。那處於使用者模式的w3wp程序如何從核心模式的佇列中取出請求呢?
w3wp中有專門幹這個的——w3dt+w3tp,可以通過process explorer
當請求被w3tp通過w3dt從http.sys的佇列中取出來後,接下來的工作就會轉交給ASP.NET,執行緒池——.NET Thread Pool。
為了檢驗.net 執行緒池 最大執行緒數的限制,在MVC中新增一個Action 如下
每個task sleep 1s ,這樣執行緒池就會被佔用最多20W條執行緒。
設定.net執行緒池 的配置檔案地址
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\machine.config
64位系統:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\machine.config
找到這個節點 processModel
設定maxWorkerThreads =20
autoConfig=false (win10預設是true)
訪問地址:/home/TestTaskLimitCount 時
使用工具集 SysinternalsSuite procexp64.exe 檢視系統程序的詳細資訊
看到W3WP.EXE 這裡的總程序數卡在100左右,因為我這裡的4個CPU,所以maxWorkerThreads *CPUCOUNT =80 另外的27條執行緒可能是IIS執行緒池裡的。
然後當我們同時訪問該站點其他URL時,全部都在一直在等待了。
OK,重新改為
maxWorkerThreads =200
這個時候重新啟動站點,執行/home/TestTaskLimitCount 時,看到程序數很快累加到400-500之間,這個時候執行緒池並沒有被用滿,只是有些Task任務結束後丟回執行緒池後又被重新啟用。
同時再次訪問一下該站點其他URL,發現雖然載入速度稍有緩慢,但是OK沒問題的。
這個值最好根據機器效能自行配置,一般100左右,minWorkerThreads 也很重要,因為開啟執行緒的速度其實還挺慢的,每秒可以開啟幾條而已,所以預先設定好minWorkerThreads,可以預防一些突發流量。