一:背景

1. 讲故事

前几个月有位朋友找到我,说他们的的web程序没有响应了,而且监控发现线程数特别高,内存也特别大,让我帮忙看一下怎么回事,现在回过头来几经波折,回味价值太浓了。

二:程序到底经历了什么

1. 在线程上找原因

这个程序内存高,线程高,无响应,尼玛是一个复合态问题,那怎么入手呢?按经验推测,大概率是由于高线程数引发的,相信大家都知道每个线程都有自己的栈空间,所以众人拾柴火焰高,可以用 !address -summary 观察下线程栈空间。


0:000> !address -summary --- Usage Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal
Free 329 7df9`d4b93000 ( 125.976 TB) 98.42%
<unknown> 994 205`2ae2e000 ( 2.020 TB) 99.81% 1.58%
Stack 7215 0`e0d00000 ( 3.513 GB) 0.17% 0.00%
Heap 956 0`1695f000 ( 361.371 MB) 0.02% 0.00%
Image 1468 0`07b34000 ( 123.203 MB) 0.01% 0.00%
TEB 2405 0`012ca000 ( 18.789 MB) 0.00% 0.00%
Other 10 0`001d1000 ( 1.816 MB) 0.00% 0.00%
PEB 1 0`00001000 ( 4.000 kB) 0.00% 0.00%
... --- State Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal
MEM_FREE 329 7df9`d4b93000 ( 125.976 TB) 98.42%
MEM_RESERVE 3132 203`e925c000 ( 2.015 TB) 99.56% 1.57%
MEM_COMMIT 9917 2`42201000 ( 9.033 GB) 0.44% 0.01%

从卦中可以清晰的看到,提交内存是9G,同时Stack吃掉了3.5G,一般来说 Stack 不会有这么大,所以此事必有妖,在 TEB 中可以看到线程数高达 2405 个,这个确实不少哈,可以用 !t 做一个验证。


0:000> !t
ThreadCount: 2423
UnstartedThread: 0
BackgroundThread: 2388
PendingThread: 0
DeadThread: 34
Hosted Runtime: no
Lock
DBG ID OSID ThreadOBJ State GC Mode GC Alloc Context Domain Count Apt Exception
0 1 3344 00000032972B2D90 202a020 Preemptive 0000000000000000:0000000000000000 0000003297125a30 -00001 MTA
11 2 1d28 00000037A43B9140 2b220 Preemptive 000000364BC5AD90:000000364BC5C328 0000003297125a30 -00001 MTA (Finalizer)
12 5 2a00 00000037A52BF4D0 102a220 Preemptive 00000036527EBDE8:00000036527EDD90 0000003297125a30 -00001 MTA (Threadpool Worker)
13 7 3168 00000037A52C1B40 302b220 Preemptive 00000034D1136688:00000034D1137FD0 0000003297125a30 -00001 MTA (Threadpool Worker)
15 14 13b8 00000037A542EA50 202b220 Preemptive 00000036527EBCA8:00000036527EBD90 0000003297125a30 -00001 MTA
...

有了这个入口点,接下来观察每一个线程的线程栈,使用 ~*e !clrstack发现有大量的线程在 PostMethod 方法中的 Task.Result 上等待,看样子是在做网络请求,这里做了一下提前截断,截图如下:

由于是知名券商,这里就尽量模糊了哈。。。请见谅,知道了在 Task.Result 上,一下子就开心起来了,自此也被误入歧途。。。。

2. 误入歧途

  1. 是上下文导致的吗?

过往经验告诉我,很多时候的 Task.Result 卡死是因为上下文的关系所致,所以重点看下是不是 Asp.NET 的程序,使用 !eeversion 观察便知。


0:000> !eeversion
6.0.422.16404 free
6,0,422,16404 @Commit: be98e88c760526452df94ef452fff4602fb5bded
Server mode with 8 gc heaps
SOS Version: 7.0.8.30602 retail build

从卦中数据看当前是 .net6 写的程序,就不存在上下文一说了,这个情况可以排除,只能继续寻找其他突破口。。。

  1. 下游处理过慢导致的吗?

是不是下游处理过慢,一个突破点就是观察下 线程池队列 是不是有任务积压,这个可以用 !tp 观察下队列即可。

从卦中数据看当前队列无任何积压,说明也不是下游处理过慢导致的,我去,太难了。。。

  1. 代理或者服务器有问题吗?

既然无上下文,无积压,接下来只能怀疑是不是server方有问题或者用了什么代理软件?要想找这个信息,需要用 !dso 观察线程栈中的对象。


0:000> ~34s
ntdll!NtWaitForMultipleObjects+0xa:
00007ffe`115c0cba c3 ret
0:034> !dso
OS Thread Id: 0x1ef4 (34)
RSP/REG Object Name
00000037B56AC688 000000351f9e4918 System.Threading.Thread
00000037B56AC700 0000003317bb6160 System.Net.Http.DiagnosticsHandler
00000037B56AC708 000000351f9e4918 System.Threading.Thread
00000037B56AC748 0000003617b743c8 System.Net.Http.HttpWindowsProxy
...
00000037B56AD0D0 00000034c8283750 System.String http://xxx/Article/xxx
00000037B56ACF30 0000003317bb5ad8 System.Net.Http.HttpClient
...

看了下卦中的请求地址:http://xxx/Article/xxx, 同时在 HttpWindowsProxyHttpClient 中也没有看到所谓的代理IP,这就陷入了迷茫。

事已至此,只能怀疑是网络的问题,让朋友在程序卡死的那个期间段用 wireshark 或者 tcpdump 去抓下包,看看是不是网络出了问题,tcp握手挥手怎么样,事情也就这样不了了之了。

3. 迷途知返

前些天在给训练营的朋友准备课件时,优化了一个例子来演示 线程池队列 的堆积情况,结果意外发现 sos 吐出来的数据是假的,尼妈,如梦初醒,分析dump已经够难了,为什么 sos 还要欺骗我,天真的塌下来了。。。

其实在分析 .net core 的dump时,每每发现线程池队列都是 0 ,虽然有一丝奇怪,但也不敢怀疑sos吐出来的数据权威性。

既然 sos 吐出来的数据是假的,只能自己去线程池中把队列挖出来,即 ThreadPoolWorkQueue.workItems 字段,如下所示:


0:034> !DumpObj /d 0000003517b9c1c0
Name: System.Threading.ThreadPoolWorkQueue
MethodTable: 00007ffd8416d260
EEClass: 00007ffd84196ab8
Tracked Type: false
Size: 168(0xa8) bytes
File: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.4\System.Private.CoreLib.dll
Fields:
MT Field Offset Type VT Attr Value Name
00007ffd83ddbf28 4000c61 18 System.Boolean 1 instance 0 loggingEnabled
00007ffd83ddbf28 4000c62 19 System.Boolean 1 instance 0 _dispatchTimeSensitiveWorkFirst
00007ffd8416dc78 4000c63 8 ...Private.CoreLib]] 0 instance 0000003517b9c268 workItems
00007ffd8416e458 4000c64 10 ...Private.CoreLib]] 0 instance 0000003517b9eea0 timeSensitiveWorkQueue
00007ffd8416d1f0 4000c65 20 ...acheLineSeparated 1 instance 0000003517b9c1e0 _separated ... 0:034> !ext dcq 0000003517b9c268
System.Collections.Concurrent.ConcurrentQueue<System.Object>
1 - dumpobj 0x00000032c93b7ce0
2 - dumpobj 0x00000032c93b8ae8
3 - dumpobj 0x00000032c93b98d8
...
54346 - dumpobj 0x00000034d12fb2e8
54347 - dumpobj 0x0000003652805b40
---------------------------------------------
54347 items

从卦中数据看当前线程池堆积了 5.3w 的任务,很显然是属于第二种情况,即下游处理不及,既然处理不急,是不是遇到了什么高峰期呢?这个可以用 .time 观察下当前时段。

从卦中数据看,看样子是快到 收盘时间 了,结合今年的大盘形式,看样子是出现了暴跌,股民们在发泄情绪,哈哈。。。

找到了问题的根,解决方案就比较多了。

  • 做 PostMethod 请求的异步化,不要用 Result 去硬等待。

  • 尽量做批量化提交,降低请求接口的单次时间。

三:总结

这次生产事故的分析峰回路转,本来是一个很容易就能定位出的问题,可我认为权威的sos居然吐出了假数据欺骗了我,让我误入歧途,浪费了很多的人力物力,真的很无语。。。再也不相信 sos 了!

记一次 .NET 某券商论坛系统 卡死分析的更多相关文章

  1. 记一次 .NET 某资讯论坛 CPU爆高分析

    大概有11天没发文了,真的不是因为懒,本想前几天抽空写,不知道为啥最近求助的朋友比较多,一天都能拿到2-3个求助dump,晚上回来就是一顿分析,有点意思的是大多朋友自己都分析了几遍或者公司多年的牛皮藓 ...

  2. 记一次 .NET 某医疗住院系统 崩溃分析

    一:背景 1. 讲故事 最近收到了两起程序崩溃的dump,查了下都是经典的 double free 造成的,蛮有意思,这里就抽一篇出来分享一下经验供后面的学习者避坑吧. 二:WinDbg 分析 1. ...

  3. 记一次 .NET某医疗器械清洗系统 卡死分析

    一:背景 1. 讲故事 前段时间协助训练营里的一位朋友分析了一个程序卡死的问题,回过头来看这个案例比较经典,这篇稍微整理一下供后来者少踩坑吧. 二:WinDbg 分析 1. 为什么会卡死 因为是窗体程 ...

  4. 记一次 .NET 某药品仓储管理系统 卡死分析

    一:背景 1. 讲故事 这个月初,有位朋友wx上找到我,说他的api过一段时间后,就会出现只有请求,没有响应的情况,截图如下: 从朋友的描述中看样子程序是被什么东西卡住了,这种卡死的问题解决起来相对简 ...

  5. 记一次 .NET 某金融企业 WPF 程序卡死分析

    一:背景 1. 讲故事 前段时间遇到了一个难度比较高的 dump,经过几个小时的探索,终于给找出来了,在这里做一下整理,希望对大家有所帮助,对自己也是一个总结,好了,老规矩,上 WinDBG 说话. ...

  6. 记一次 .NET 某数控机床控制程序 卡死分析

    一:背景 1. 讲故事 前段时间有位朋友微信上找到我,说它的程序出现了卡死,让我帮忙看下是怎么回事? 说来也奇怪,那段时间求助卡死类的dump特别多,被迫训练了一下对这类问题的洞察力 ,再次声明一下, ...

  7. RHEL6 --部署phpMyAdmin与论坛系统

    一.rpm安装LAMP平台部署phpMyAdmin 二.搭建wordpress个人博客系统 三.搭建论坛系统 一.rpm安装LAMP平台及部署phpMyAdmin 1.phpMyAdmin简介及获取方 ...

  8. 基于JSP的学术交流论坛系统的设计与实现

    版权声明:本文为[博主](https://zhangkn.github.io)原创文章.未经博主同意不得转载. https://creativecommons.org/licenses/by-nc-s ...

  9. 想要搭建个论坛?Guide哥调研了100来个 Java 开源论坛系统,发现这 5 个最好用!

    大家好!我是 Guide 哥,Java 后端开发.一个会一点前端,喜欢烹饪的自由少年. 最近有点小忙.但是,由于前几天答应了一位读者自己会推荐一些开源的论坛系统,所以,昨晚就简单地熬了个夜,对比了很多 ...

  10. Java,面试题,简历,Linux,大数据,常用开发工具类,API文档,电子书,各种思维导图资源,百度网盘资源,BBS论坛系统 ERP管理系统 OA办公自动化管理系统 车辆管理系统 各种后台管理系统

    Java,面试题,简历,Linux,大数据,常用开发工具类,API文档,电子书,各种思维导图资源,百度网盘资源BBS论坛系统 ERP管理系统 OA办公自动化管理系统 车辆管理系统 家庭理财系统 各种后 ...

随机推荐

  1. JVM调优篇:探索Java性能优化的必备种子面试题

    JVM内存模型 首先面试官会询问你在进行JVM调优之前,是否了解JVM内存模型的基础知识.这是一个重要的入门问题.JVM内存模型主要包括程序计数器.堆.本地方法栈.Java栈和方法区(1.7之后更改为 ...

  2. 使用 FastGPT 构建高质量 AI 知识库

    作者:余金隆.FastGPT 项目作者,Sealos 项目前端负责人,前 Shopee 前端开发工程师 FastGPT 项目地址:https://github.com/labring/FastGPT/ ...

  3. 在 ubuntu 中安装或升级最新版本的 Elasticsearch

    1. 安装 java 8 首先最新版本的elasticsearch需要java8的支持,那先来安装一下. $ sudo add-apt-repository -y ppa:webupd8team/ja ...

  4. 加密解决HTTP协议带来的安全问题

    HTTP协议默认是采取明文传输的,容易被中间人窃听.拦截.篡改,存在安全隐患. 常见提高安全性的方法是对通信内容进行加密,再进行传输,常见的加密方式有 不可逆加密:单向散列函数 可逆加密:对称加密.非 ...

  5. Cilium系列-15-7层网络CiliumNetworkPolicy简介

    系列文章 Cilium 系列文章 前言 今天我们进入 Cilium 安全相关主题, 介绍 CiliumNetworkPolicies 相比于 Kubernetes 网络策略最大的不同: 7 层网络策略 ...

  6. [jmeter]简介与安装

    简介 JMeter是开源软件Apache基金会下的一个性能测试工具,用来测试部署在服务器端的应用程序的性能. 安装 安装jmeter 从 官网 下载jmeter的压缩包 安装jdk并配置 JAVA_H ...

  7. 分布式TCC事务相关问题

    TCC分别是Try,Confirm,Cancel,分为三阶段. 第一阶段Try:业务检查及资源预留,尝试事务操作但不提交. 第二阶段Confirm:事务操作提交. 第三阶段Cancel:如果Try阶段 ...

  8. jenkins部署及gitlab联调

    jenkins部署及gitlab联调 目录 jenkins部署及gitlab联调 一.jenkins安装 1.环境优化 2.安装jdk java 环境 3.下载jenkins 4.启动Jenkins服 ...

  9. GORM自定义Gorm.Model实现自动添加时间戳

    废话不说直接开始 官网(http://gorm.io)有给出一套默认的gorm.Model模型,定义如下 package gorm import "time" // Model b ...

  10. ES 2023新特性速解

    ES 2023新特性速解 一.新增数组方法 操作数组的方法 Array.prototype.toSorted(compareFn) //返回一个新数组,其中元素按升序排序,而不改变原始数组. Arra ...