真正解決ASP.NET每一個頁面首次訪問超級慢的問題
阿新 • • 發佈:2018-12-31
今天搜尋了一下,原來是這樣的:
.net程式第一次執行速度慢的問題原因是第一次執行需要驗證數字簽名。當程式裡面需要呼叫到一些 Authenticode Signed的.NET Assembly的時候,它需要連線到外網來驗證數字證書。當伺服器是無法連線到外網時,這個校驗證書的過程需要等到timeout之後才會結束。
那麼要做的就是不讓它幹這些壞事,總之我從來都不覺得它會老老實實的給你服務。
禁止證書的驗證過程:
1、在下面aspnet.config檔案中加入下面內容:
32位系統:C:\Windows\Microsoft.Net\Framework\v2.0.50727\aspnet.config
64位系統:C:\Windows\Microsoft.NET\Framework64\v2.0.50727\aspnet.config
有4.0,甚至4.5的自己多改幾個地方,如果是64位的系統,可能需要以管理員身份開啟編輯器,再開啟這個檔案,否則無法儲存的。
- <?xmlversion="1.0"encoding="utf-8"?>
- <configuration>
- <runtime>
- <generatePublisherEvidenceenabled="false"/>
- </runtime>
- </configuration>
對"Network Service"帳號下執行的所有程式禁止證書檢查
不會的話就忽略吧。
匯入以下注冊表內容,自己先另存為*.reg檔案吧,如果會手工操作的話,就手工來吧。
- Windows Registry Editor Version 5.00
- [HKEY_USERS\S-1-5-20\Software\Microsoft\Windows\CurrentVersion\WinTrust\Trust Providers\Software Publishing]
- "State"=dword:00023e00
然後記得重啟一下應用程式池(實在不知道,就重啟IIS服務),再去看看你的網站,首次載入快嗎?其它頁面訪問快嗎?
忍受不了時,就再也不用忍受!
下面是專業的分析記錄,看不懂就當沒見過吧。。。
- 詳細分析
- ==========
- 這個時候如果我們抓取一個hang dump的話,頁面所對應的managed callstack往往如下,很明顯它正在載入一個Assembly
- 0:022> !CLRStack
- OS Thread Id: 0xeb4 (22)
- Child-SP RetAddr Call Site
- 000000001af1c900 000007fef91747c3 System.Reflection.Assembly.InternalLoad(System.Reflection.AssemblyName, System.Security.Policy.Evidence,
- System.Threading.StackCrawlMark ByRef, Boolean)
- 000000001af1c990 000007ff0141f0f9 System.Reflection.Assembly.Load(System.Reflection.AssemblyName)
- 000000001af1c9d0 000007fef9fdd502 Microsoft.SharePoint.Portal.WebControls.StringResourceManager..cctor()
- 000000001af1db50 000007ff014135e2 Microsoft.SharePoint.Portal.WebControls.MySiteLinkUserControl.SetControl()
- 000000001af1dce0 000007fef398e04f Microsoft.SharePoint.Portal.WebControls.MySiteLinkUserControl.OnInit(System.EventArgs)
- 000000001af1de80 000007fef398f3af System.Web.UI.Control.InitRecursive(System.Web.UI.Control)
- 000000001af1dee0 000007ff014133c8 System.Web.UI.Control.AddedControl(System.Web.UI.Control, Int32)
- 000000001af1df50 000007ff0134115e Microsoft.SharePoint.WebControls.DelegateControl.AddControlResilient(System.Web.UI.Control)
- 000000001af1dff0 000007fef398fb22 Microsoft.SharePoint.WebControls.DelegateControl.CreateChildControls()
- 000000001af1e170 000007ff01341024 System.Web.UI.Control.EnsureChildControls()
- 000000001af1e1d0 000007fef398e04f Microsoft.SharePoint.WebControls.DelegateControl.OnInit(System.EventArgs)
- 000000001af1e210 000007fef398e147 System.Web.UI.Control.InitRecursive(System.Web.UI.Control)
- 000000001af1e270 000007fef398e147 System.Web.UI.Control.InitRecursive(System.Web.UI.Control)
- 000000001af1e2d0 000007fef398e147 System.Web.UI.Control.InitRecursive(System.Web.UI.Control)
- 000000001af1e330 000007fef398e147 System.Web.UI.Control.InitRecursive(System.Web.UI.Control)
- 000000001af1e390 000007fef398e147 System.Web.UI.Control.InitRecursive(System.Web.UI.Control)
- 000000001af1e3f0 000007fef398a935 System.Web.UI.Control.InitRecursive(System.Web.UI.Control)
- 000000001af1e450 000007fef398a1f0 System.Web.UI.Page.ProcessRequestMain(Boolean, Boolean)
- 000000001af1e520 000007fef398a11b System.Web.UI.Page.ProcessRequest(Boolean, Boolean)
- 000000001af1e580 000007fef398a0b0 System.Web.UI.Page.ProcessRequest()
- 000000001af1e5e0 000007fef3991557 System.Web.UI.Page.ProcessRequest(System.Web.HttpContext)
- 000000001af1e640 000007fef395567b System.Web.HttpApplication+CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
- 000000001af1e6f0 000007fef39634b5 System.Web.HttpApplication.ExecuteStep(IExecutionStep, Boolean ByRef)
- 000000001af1e790 000007fef3954733 System.Web.HttpApplication+ApplicationStepManager.ResumeSteps(System.Exception)
- 000000001af1e840 000007fef3958a54 System.Web.HttpApplication.System.Web.IHttpAsyncHandler.BeginProcessRequest(System.Web.HttpContext, System.AsyncCallback,
- System.Object)
- 000000001af1e8a0 000007fef395863c System.Web.HttpRuntime.ProcessRequestInternal(System.Web.HttpWorkerRequest)
- 000000001af1e930 000007fef395726c System.Web.HttpRuntime.ProcessRequestNoDemand(System.Web.HttpWorkerRequest)
- 000000001af1e970 000007fef9fdd502 System.Web.Hosting.ISAPIRuntime.ProcessRequest(IntPtr, Int32)
- 其實它所要載入的Assembly名字如下
- Microsoft.SharePoint.Portal.intl
- 此執行緒所對應的native callstack如下
- 0:022> k20
- Child-SP RetAddr Call Site
- 00000000'1af1a208 000007fe'fdc610ac ntdll!ZwWaitForSingleObject+0xa
- 00000000'1af1a210 000007fe'f5dfa2fa KERNELBASE!WaitForSingleObjectEx+0x79 00000000'1af1a2b0 000007fe'f5df76fa cryptnet!CryptRetrieveObjectByUrlWithTimeout+0x263
- 00000000'1af1a5b0 000007fe'f5df4646 cryptnet!CryptRetrieveObjectByUrlW+0x20f 00000000'1af1a7a0 000007fe'f5df9c34 cryptnet!RetrieveObjectByUrlValidForSubject+0x162 00000000'1af1a8d0 000007fe'f5df4243 cryptnet!RetrieveTimeValidObjectByUrl+0x2de 00000000'1af1a9c0 000007fe'f5df3c72 cryptnet!CTVOAgent::GetTimeValidObjectByUrl+0x2e3 00000000'1af1ab20 000007fe'f5df38ad cryptnet!CTVOAgent::GetTimeValidObject+0x7cf
- 00000000'1af1ad00 000007fe'f5df3810 cryptnet!FreshestCrlFromCrlGetTimeValidObject+0x61
- 00000000'1af1ad70 000007fe'f5df99fc cryptnet!CryptGetTimeValidObject+0xb0 00000000'1af1adf0 000007fe'f5df345d cryptnet!GetTimeValidCrl+0x4b7
- 00000000'1af1af30 000007fe'f5df3f82 cryptnet!GetBaseCrl+0x7d 00000000'1af1afc0 000007fe'f5df3d58 cryptnet!MicrosoftCertDllVerifyRevocation+0x238
- 00000000'1af1b110 000007fe'fdb157c7 cryptnet!CertDllVerifyRevocation+0x28
- 00000000'1af1b160 000007fe'fdb1552e crypt32!VerifyDefaultRevocation+0x398 00000000'1af1b250 000007fe'fdb15c09 crypt32!CertVerifyRevocation+0x144
- ...
- 00000000'1af1bcc0 000007fe'f9e46c27 mscorwks!PEFile::CheckSecurity+0x39b924
- 00000000'1af1bd50 000007fe'f9e5eb5d mscorwks!PEAssembly::DoLoadSignatureChecks+0x37
- 00000000'1af1bd90 000007fe'f9e52ff8 mscorwks!PEAssembly::PEAssembly+0x12d 00000000'1af1be00 000007fe'f9e40b9d mscorwks!PEAssembly::DoOpen+0x11c 00000000'1af1c130 000007fe'f9f24a3e mscorwks!PEAssembly::Open+0x71
- 從這些函式名我們知道它正在做一些證書檢查之類的事情。而實際上它正在等待下面的這個執行緒。
- 0:036> kn
- # Child-SP RetAddr Call Site
- 00 00000000'2409e1c8 000007fe'fdc610ac ntdll!ZwWaitForSingleObject+0xa
- 01 00000000'2409e1d0 000007fe'f5d7f38e KERNELBASE!WaitForSingleObjectEx+0x79
- 02 00000000'2409e270 000007fe'f5d80a27 winhttp!IsWpadEnabledForConnectedNetworks+0x1f2
- 03 00000000'2409e340 000007fe'f5d806dc winhttp!ReadWinInetProxySettings+0x1c3
- 04 00000000'2409e3c0 000007fe'f5dfae42 winhttp!WinHttpGetIEProxyConfigForCurrentUser+0x28a
- 05 00000000'2409e510 000007fe'f5df9237 cryptnet!InetGetProxy+0x11e
- 06 00000000'2409e600 000007fe'f5df983d cryptnet!InetSendAuthenticatedRequestAndReceiveResponse+0x190
- 07 00000000'2409f770 000007fe'f5df9d9c cryptnet!InetSendReceiveUrlRequest+0x57e
- .....
- 0:036> .frame 7
- 07 00000000'2409f770 000007fe'f5df9d9c cryptnet!InetSendReceiveUrlRequest+0x57e [d:\w7rtm\ds\security\cryptoapi\pki\rpor\inetsp.cpp @ 2603]
- 0:036> dv
- hInetSession = 0x00000000'218211f0
- pwszUrl = 0x00000000'1f8abe50 "http://crl.microsoft.com/pki/crl/products/CSPCA.crl"
- dwRetrievalFlags = 1
- pCredentials = 0x00000000'00000000
- pcba = 0x00000000'2409fab0
- ppfnFreeObject = 0x00000000'2409fb38
- ppvFreeContext = 0x00000000'2409fb30
- pAuxInfo = 0x00000000'1f8abd78
- phInetRequest = 0x00000000'00000000
- 我們可以看到,當時我們抓取dump的時候它正在嘗試連線http://crl.microsoft.com/pki/crl/products/CSPCA.crl