【记一次 .NET 某娱乐聊天流平台 CPU 爆高分析】从线程栈上看,这个 CPU 是 4个核,刚好对应着 4 个 HandleError 报错,看样子是什么网络出问题了,接下来切到 80 号线程看一下有没有什么异常类 。
0:000> ~80sclr!AwareLock::Contention+0x194:00007ffa`deb86e40 4883e801 sub rax,10:080> !mdsoThread 80:Location Object Type------------------------------------------------------------000000000d24e098 000000015765e028 System.Net.WebException000000000d24e0f8 0000000340b07110 System.Collections.ArrayList000000000d24e110 000000015765e2b8 System.Net.HttpWebRequest[]000000000d24e1c0 0000000340b070b8 System.Net.ConnectionGroup000000000d24e258 0000000144a79678 System.Net.Connection0:080> !mdt 000000015765e028000000015765e028 (System.Net.WebException) _className:NULL (System.String) _exceptionMethod:NULL (System.Reflection.MethodBase) _exceptionMethodString:NULL (System.String) _message:000000015765df70 (System.String) Length=77, String="The underlying connection was closed: The connection was closed unexpectedly." ...果然看到了 System.Net.WebException, 从异常信息看貌似是 连接关闭了,到这里我就有了一个大胆的猜测,是不是高频的异常输出导致的 CPU 爆高呢? 为了验证,可以到托管堆上找下 WebException 的个数 。
0:080> !dumpheap -statStatistics: MT Count TotalSize Class Name...00007ffacecc38b0 13315 2343440 System.Net.WebException00007ffadcdf6570 11369 1909992 System.IO.IOException00007ffadcdf5fb8 13380 2247840 System.ObjectDisposedException...看到这么多异常还是挺吓人的,刚好朋友抓了两个dump可以做个比较 。
0:048> !dumpheap -statStatistics: MT Count TotalSize Class Name00007ffacecc38b0 26745 4707120 System.Net.WebException00007ffadcdf6570 26722 4489296 System.IO.IOException00007ffadcdf5fb8 28745 4829160 System.ObjectDisposedException可以看到 , 2 min 之内异常增加了合计 4w 左右,这就验证了程序确实是疯狂的抛异常,在 Windows 平台上不管是硬件异常还是软件异常都由 Windows SEH 异常处理框架统一处理 , 会出现用户态和内核态的切换,这样疯狂的抛出 , 必然会导致 CPU 爆高 , 终于找到原因了,接下来就是寻找诱发因素 。
3. 异常是谁诱发的再回头看 HandleError 函数的调用栈都是底层的库函数,从线程栈的 PerformIOCompletionCallback 函数来看是 IO线程 诱发的,能被 IO 线程兜到是因为这是做了异步处理,既然是 异步,自然 OverlappedData 也会非常多 。
0:080> !gchandles -statStatistics: MT Count TotalSize Class Name00007ffadc6f7b98 14511 1625232 System.Threading.OverlappedDataTotal 17550 objectsHandles: Strong Handles: 426 Pinned Handles: 23 Async Pinned Handles: 14511 Ref Count Handles: 24 Weak Long Handles: 2430 Weak Short Handles: 132 SizedRef Handles: 4说明此时有大概 1.5w 的异步请求待回头,请求量还是蛮大的,但还是没找到异常的用户代码,只能找下到底是谁发起了什么请求 。
0:080> !mdsoThread 80:Location Object Type------------------------------------------------------------...000000000d24e488 0000000358c57918 System.Net.HttpWebRequest000000000d24e2e8 00000001407b5b40 System.String "net_io_readfailure"...0:080> !mdt -r:2 0000000358c579180000000358c57918 (System.Net.HttpWebRequest) _Uri:0000000358c57210 (System.Uri) m_String:00000002407ee430 (System.String) Length=98, String="https://api.xxxx/peer_messages" ....
推荐阅读
- MassTransit | .NET 分布式应用框架
- 怎么开保险柜新买的保险柜打不开了,忘记怎么开了
- 4 .NET 6学习笔记——如何在.NET 6的Desktop App中使用Windows Runtime API
- 学习ASP.NET Core Blazor编程系列八——数据校验
- GitHub Pages 和 Jekyll 笔记
- 【.NET 6】RabbitMQ延迟消费指南
- 中铁十六局个人门户网忘记密码咋办 中铁十六局门户网站
- [Oracle]复习笔记-SQL部分内容
- 之四 2流高手速成记:SpringBoot整合redis及mongodb
- 简读《ASP.NET Core技术内幕与项目实战》之3:配置