我们有一个使用 Entity Framework 4.0 的 ASP.NET MVC4 应用程序。当我们部署在生产服务器上时,CPU 会在一段时间(~2-5h)后上升,直到接近 100%。然后内存也会上升直到最大值。一段时间后,由于内存过高,应用程序池将自动重置。
服务器:Windows 2008 R2 标准 SP1 IIS:7(V 7.5.7600.16385) 仅一个应用程序池和一个 Web 应用程序正在运行。
来自消耗大部分 CPU 的线程的调试诊断工具的堆栈跟踪:
SNIReadSyncOverAsync(SNI_ConnWrapper*, SNI_Packet**, Int32)
.SNIReadSyncOverAsync(SNI_ConnWrapper*, SNI_Packet**, Int32)
System.Web.Hosting.UnsafeIISMethods.MgdIndicateCompletion(IntPtr, System.Web.RequestNotificationStatus ByRef)
System.Web.Hosting.UnsafeIISMethods.MgdIndicateCompletion(IntPtr, System.Web.RequestNotificationStatus ByRef)
ntdll!NtWaitForSingleObject
KERNELBASE!WaitForSingleObjectEx
System_Data!SNIReadSyncOverAsync
System_Data_ni!load_config_used
System_Data_ni!load_config_used
System_Data_ni!load_config_used
System_Data_ni!load_config_used
System_Data_ni!load_config_used
System_Data_ni!load_config_used
System_Data_ni!load_config_used
System_Data_ni!load_config_used
System_Data_ni!load_config_used
System_Data_ni!load_config_used
System_Data_ni!load_config_used
System_Data_ni!load_config_used
System_Data_ni!load_config_used
System_Data_ni!load_config_used
System_Data_ni!load_config_used
System_Data_Entity_ni
System_Data_Entity_ni
System_Data_Entity_ni
System_Data_Entity_ni
System_Core_ni
System_Core_ni
0x000007fe`99223112
0x000007fe`99222a88
0x000007fe`99222899
0x000007fe`992205cb
0x000007fe`99355596
System_Web_Mvc_ni+138058
System_Web_Mvc_ni+13ca67
System_Web_Mvc_ni+13e71c
System_Web_Mvc_ni+13ca03
System_Web_Mvc_ni+13d175
System_Web_Mvc_ni+13cbe9
System_Web_Mvc_ni+1431df
System_Web_Mvc_ni+13dade
System_Web_Mvc_ni+14f5fe
System_Web_Mvc_ni+13b0ef
System_Web_Mvc_ni+14f514
System_Web_ni
System_Web_ni
System_Web_ni
System_Web_ni
System_Web_ni
System_Web_ni
System_Web_ni
System_Web_ni
clr!UMThunkStub
webengine4!W3_MGD_HANDLER::ProcessNotification
webengine4!W3_MGD_HANDLER::DoWork
webengine4!RequestDoWork
webengine4!CMgdEngHttpModule::OnExecuteRequestHandler
iiscore!NOTIFICATION_CONTEXT::RequestDoWork
iiscore!NOTIFICATION_CONTEXT::CallModulesInternal
iiscore!NOTIFICATION_CONTEXT::CallModules
iiscore!W3_CONTEXT::DoWork
iiscore!W3_CONTEXT::IndicateCompletion
webengine4!MgdIndicateCompletion
System_Web_ni
System_Web_ni
System_Web_ni
System_Web_ni
clr!UM2MThunk_WrapperHelper
clr!UM2MThunk_Wrapper
clr!Thread::DoADCallBack
clr!UM2MDoADCallBack
clr!UMThunkStub
webengine4!W3_MGD_HANDLER::ProcessNotification
webengine4!ProcessNotificationCallback
clr!UnManagedPerAppDomainTPCount::DispatchWorkItem
clr!ThreadpoolMgr::ExecuteWorkRequest
clr!ThreadpoolMgr::WorkerThreadStart
clr!Thread::intermediateThreadProc
kernel32!BaseThreadInitThunk
ntdll!RtlUserThreadStart
你知道这个CPU上升的原因是什么吗?
嘿,我使用大量线程时间使用
SNIReadSyncOverAsync
遇到了完全相同的问题(我使用 DebugDiag 发现了这一点)。
我不知道这是否对其他人有帮助,但看起来我们的问题出在我们使用的 Azure DB 服务器上。我们将其设置为仅 50 个 DTU,最多有 100 个并发请求。
基本上
SNIReadSyncOverAsync
之所以这么大,是因为 Web 服务器必须坐在那里等待 DB 服务器的响应,而 DB 服务器一次只能处理 100 个请求,因此 Web 服务器最终会等待很长时间(导致CPU 使用率 100% 且网站无法访问)。最近网络流量增加时可能会出现这种情况(例如:如果你们最近购买了广告并看到网络流量大幅增加,那么现在 100 个并发请求还不够)
因此,如果您像我们一样并且正在使用 Azure DB,请检查您的 DTU 使用率百分比。如果它经常很高(80-90%等),请尝试将其增加到两倍甚至四倍(这可能会很昂贵!)。我们从“弹性标准”(50 个 eDTU)升级到“标准 S4”(400 个 DTU),但我们尚未看到 CPU 使用率达到 100%。事实上,自那以后它一直在 7-9% 左右浮动。
Dotnet 8 webapi multitenant multi-database
应用程序,同样的问题。我们发现我们的部分数据库位于 SQLEXPRESS 上,因此我们将它们转移到完整的 MSSQL DBMS 版本上。这有帮助