向你們分享一下最近排查「黑色1秒」問題的進展,「黑色1秒」的問題表現詳見什麼是黑色1秒。html
1. 發生在w3wp進程內web
判斷依據:「黑色1秒」期間,http.sys的HTTP Service Request Queues\ArriveRate正常,W3SVC_W3WP\Requests/Sec正常。api
2. 請求未進入.NET線程池app
判斷依據:「黑色1秒」期間靜態文件的請求也不能被處理,若是「黑色1秒」發生在.NET線程執行過程當中,靜態文件是由非託管模塊處理的,應該不受影響。oop
3. 發生在處於user-mode的IIS核心模塊spa
http.sys處於kernel-mode,處於user-mode的處理請求的IIS核心模塊有:w3tp->w3dt->iiscore->webengine->wbhst_pm,在C:\Windows\System32\inetsrv中都有對應的dll文件。線程
IIS核心模塊請求處理流程以下(自下而上,來自application pool crashes in IIS 7.5):3d
clr!ClrCreateManagedInstance webengine4!LegacyActivationShim::ClrCreateManagedInstance webengine4!GetIsapiProcessHost webengine!GetIsapiProcessHost wbhst_pm wbhst_pm!GetProtocolManager w3wphost!AppHostInitialize w3wphost!IPM_MESSAGE_PIPE::operator= iiscore!W3_SERVER::GetProtocolManagerCustomInterface webengine4!InitClrHost webengine4!CMgdEngGlobalModule::OnGlobalApplicationResolveModules iiscore!VIRTUAL_MODULE::GlobalDoWork iiscore!W3_SERVER::GlobalNotify iiscore!W3_APPLICATION::ResolveModules iiscore!W3_APPLICATION::SetupNotificationContext iiscore!W3_CONTEXT::SetupStateMachinePhase2 iiscore!W3_CONTEXT::SetupStateMachine iiscore!W3_MAIN_CONTEXT::StartNotificationLoop iiscore!W3_MAIN_CONTEXT::OnNewRequest w3dt!UL_NATIVE_REQUEST::DoStateProcess w3dt!UL_NATIVE_REQUEST::DoWork w3dt!OverlappedCompletionRoutine w3tp!THREAD_POOL_DATA::ThreadPoolThread w3tp!THREAD_MANAGER::ThreadManagerThread
4. w3tp與w3dt
code
w3tp(w3 thread pool)是IIS的線程池,在註冊表(HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\InetInfo\Parameters)中有一個設置項ThreadPoolStartDelay,默認值是1秒。htm
ThreadPoolStartDelay is how long the thread pool should set the timer for when zero threads are waiting on the completion port.
若是有線程在等待完成端口,是這樣的狀況(如下截圖來自Process Explorer):
w3dt(多是w3 data transfer的縮寫)是一個完成端口(Completion Port)處理程序,從http.sys的隊列(kernel-mode)中將請求取出至w3wp進程(user-mode)的本地隊列。
5. 猜測
在w3dt將請求從http.sys的隊列搬至w3wp本地隊列後,本應觸發iiscore!W3_MAIN_CONTEXT::OnNewRequest;但是這時某種未知緣由(懷疑是CPU的緣由)形成w3tp認爲"zero threads are waiting on the completion port",將Timer頻率改成了1秒,結果1秒後才觸發OnNewRequest,將隊列中請求轉交至後續處理環節;而在這1秒期間,ASP.NET因爲沒有收到請求,因而QPS爲0。
感慨:網上關於IIS核心模塊的資料實在太少了,IIS又不開源,只能靠「蒙猜試」了。