记一次 .NET 某券商论坛系统 卡死分析
一:背景
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: noLock DBG ID OSID ThreadOBJ State GC Mode GC Alloc Context Domain Count Apt Exception0 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. 误入歧途
- 是上下文导致的吗?
过往经验告诉我,很多时候的 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 写的程序,就不存在上下文一说了,这个情况可以排除,只能继续寻找其他突破口。。。
- 下游处理过慢导致的吗?
是不是下游处理过慢,一个突破点就是观察下 线程池队列 是不是有任务积压,这个可以用 !tp 观察下队列即可。

从卦中数据看当前队列无任何积压,说明也不是下游处理过慢导致的,我去,太难了。。。
- 代理或者服务器有问题吗?
既然无上下文,无积压,接下来只能怀疑是不是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, 同时在 HttpWindowsProxy 和 HttpClient 中也没有看到所谓的代理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 0x00000032c93b7ce02 - dumpobj 0x00000032c93b8ae83 - dumpobj 0x00000032c93b98d8...
54346 - dumpobj 0x00000034d12fb2e8
54347 - dumpobj 0x0000003652805b40
---------------------------------------------
54347 items
从卦中数据看当前线程池堆积了 5.3w 的任务,很显然是属于第二种情况,即下游处理不及,既然处理不急,是不是遇到了什么高峰期呢?这个可以用 .time 观察下当前时段。

从卦中数据看,看样子是快到 收盘时间 了,结合今年的大盘形式,看样子是出现了暴跌,股民们在发泄情绪,哈哈。。。
找到了问题的根,解决方案就比较多了。
-
做 PostMethod 请求的异步化,不要用 Result 去硬等待。
-
尽量做批量化提交,降低请求接口的单次时间。
三:总结
这次生产事故的分析峰回路转,本来是一个很容易就能定位出的问题,可我认为权威的sos居然吐出了假数据欺骗了我,让我误入歧途,浪费了很多的人力物力,真的很无语。。。再也不相信 sos 了!
相关文章:
记一次 .NET 某券商论坛系统 卡死分析
一:背景 1. 讲故事 前几个月有位朋友找到我,说他们的的web程序没有响应了,而且监控发现线程数特别高,内存也特别大,让我帮忙看一下怎么回事,现在回过头来几经波折,回味价值太浓了。 二&#…...
DevExpress WinForms HeatMap组件,一个高度可自定义热图控件!
通过DevExpress WinForms可以为Windows Forms桌面平台提供的高度可定制的热图UI组件,体验DevExpress的不同之处。 DevExpress WinForms有180组件和UI库,能为Windows Forms平台创建具有影响力的业务解决方案。同时能完美构建流畅、美观且易于使用的应用程…...
振弦传感器表面应变计与振弦采集仪形成岩土工程监测的解决方案
振弦传感器表面应变计与振弦采集仪形成岩土工程监测的解决方案 振弦传感器表面应变计与振弦采集仪可以结合使用,形成岩土工程监测的解决方案。具体的方案包括以下几个步骤: 1. 安装振弦传感器表面应变计:首先需要在需要监测的岩土结构表面安…...
笔记本电脑没有声音?几招恢复声音流畅!
笔记本电脑已经成为我们日常生活和工作的重要工具,而其中的声音是其功能之一。然而,有时您可能会遇到笔记本电脑没有声音的问题,这可能是由多种原因引起的。在本文中,我们将深入探讨笔记本电脑没有声音的常见原因,并提…...
JavaScript学习_01——JavaScript简介
JavaScript简介 JavaScript介绍 JavaScript是一种轻量级的脚本语言。所谓“脚本语言”,指的是它不具备开发操作系统的能力,而是只用来编写控制其他大型应用程序的“脚本”。 JavaScript 是一种嵌入式(embedded)语言。它本身提供…...
11.10~11.15置信区间,均值、方差假设检验,正态,t,卡方,F分布,第一第二类错误
置信度,置信区间 给定一个置信度,就可以算出一个置信区间。 如果给的置信度越大,那么阿尔法就越小 给的置信度越小,那么α就越大,那么 考虑精确性,希望区间长度尽可能小,所以是取正态的中间…...
【洛谷 P2440】木材加工 题解(二分查找+循环)
木材加工 题目背景 要保护环境 题目描述 木材厂有 n n n 根原木,现在想把这些木头切割成 k k k 段长度均为 l l l 的小段木头(木头有可能有剩余)。 当然,我们希望得到的小段木头越长越好,请求出 l l l 的最大…...
反向传播详解BP
误差反向传播(Back-propagation, BP)算法的出现是神经网络发展的重大突破,也是现在众多深度学习训练方法的基础。该方法会计算神经网络中损失函数对各参数的梯度,配合优化方法更新参数,降低损失函数。 BP本来只指损失…...
2023.11.16-hive sql高阶函数lateral view,与行转列,列转行
目录 0.lateral view简介 1.行转列 需求1: 需求2: 2.列转行 解题思路: 0.lateral view简介 hive函数 lateral view 主要功能是将原本汇总在一条(行)的数据拆分成多条(行)成虚拟表,再与原表进行笛卡尔积,…...
解决Jetson Xavier NX上Invalid CUDA ‘--device 0‘ requested等问题
解决Jetson Xavier NX上Invalid CUDA --device 0 requested等问题 问题1:AssertionError: Invalid CUDA --device 0 requested, use --device cpu or pass valid CUDA device(s)问题2: “Illegal instruction(cpre dumped)”错误记录python http局域网文…...
git push 报错 The requested URL returned error: 500
今天gitpush时报错The requested URL returned error: 500 看报错应该是本地和gitlab服务器之间通信的问题,登录gitlab网站查看 登录时报错无法通过ldapadmin认证,ldap服务器连接失败。 首先,登录ldap服务器,查看是否是ldap服务…...
应用软件安全编程--17预防基于 DOM 的 XSS
DOM型XSS从效果上来说也属于反射型XSS,由于形成的原因比较特殊所以进行单独划分。在网站页面中有许多页面的元素,当页面到达浏览器时浏览器会为页面创建一个顶级的Document object 文档对象,接着生成各个子文档对象,每个页面元素对应一个文档…...
【FastCAE源码阅读9】鼠标框选网格、节点的实现
一、VTK的框选支持类vtkInteractorStyleRubberBandPick FastCAE的鼠标事件交互类是PropPickerInteractionStyle,它扩展自vtkInteractorStyleRubberBandPick。vtkInteractorStyleRubberBandPick类可以实现鼠标框选物体,默认情况下按下键盘r键开启框选模式…...
【ArcGIS处理】行政区划与流域区划间转化
【ArcGIS处理】行政区划与流域区划间转化 引言数据准备1、行政区划数据2、流域区划数据 ArcGIS详细处理步骤Step1:统计行政区划下子流域面积1、创建批量处理模型2、添加批量裁剪处理3、添加计算面积 Step2:根据子流域面积占比均化得到各行政区固定值 参考…...
Session、Token、Jwt三种登录方案介绍
新开发一个应用首先要考虑的就是登录怎么去做,登录本身就是判断一下输入的用户名和密码与系统存储的是否一致,但因为Http是无状态协议,用户请求其它接口时是怎么判断该用户已经登录了呢?下面聊一个三种实现方案。 一、传统sessio…...
Linux操作系统使用及C高级编程-D5Linux shell命令(进程管理、用户管理)
进程管理 查看进程ps 其中ps -eif可显示父进程 实时查看进程top 按q退出 树状图显示进程pstree 以父进程,子进程以树状形式展示 发送信号kill kill -l:查看都有哪些信号 9:进程终止 kill不指定信号,默认发送的是15信号SIGT…...
【TDSQL-PG数据库简单介绍】
TDSQL-PG数据库简单介绍 TDSQL-PGTDSQL-PG 设计目标 TDSQL-PG 腾讯 TDSQL-PG 分布式关系型数据库是一款面向海量在线实时分布式事务交易和 MPP 实时数据分析 通用型高性能数据库系统。 面对应用业务产生的不定性数据爆炸需求,不管是高并发的交易还是海量的实时数据…...
【文件包含】metinfo 5.0.4 文件包含漏洞复现
1.1漏洞描述 漏洞编号————漏洞类型文件包含漏洞等级⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐漏洞环境windows攻击方式 MetInfo 是一套使用PHP 和MySQL 开发的内容管理系统。MetInfo 5.0.4 版本中的 /metinfo_5.0.4/about/index.php?fmodule文件存在任意文件包含漏洞。攻击者可利用漏洞读取网…...
差分信号的末端并联电容到底有什么作用?
差分信号的末端并联电容到底有什么作用? 在现代电子系统中,差分信号是一种常见的信号形式,它们通过两根互补的信号线传输信号,具有较低的噪声和更高的抗干扰能力。然而,当差分信号线长度较长或者遇到复杂的电路环境时&…...
pandas教程:GroupBy Mechanics 分组机制
文章目录 Chapter 10 Data Aggregation and Group Operations(数据汇总和组操作)10.1 GroupBy Mechanics(分组机制)1 Iterating Over Groups(对组进行迭代)2 Selecting a Column or Subset of Columns (选中…...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...
渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...
ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...
Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...
go 里面的指针
指针 在 Go 中,指针(pointer)是一个变量的内存地址,就像 C 语言那样: a : 10 p : &a // p 是一个指向 a 的指针 fmt.Println(*p) // 输出 10,通过指针解引用• &a 表示获取变量 a 的地址 p 表示…...
绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化
iOS 应用的发布流程一直是开发链路中最“苹果味”的环节:强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说,这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发(例如 Flutter、React Na…...
6.9-QT模拟计算器
源码: 头文件: widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QMouseEvent>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent nullptr);…...
从零开始了解数据采集(二十八)——制造业数字孪生
近年来,我国的工业领域正经历一场前所未有的数字化变革,从“双碳目标”到工业互联网平台的推广,国家政策和市场需求共同推动了制造业的升级。在这场变革中,数字孪生技术成为备受关注的关键工具,它不仅让企业“看见”设…...
深度解析云存储:概念、架构与应用实践
在数据爆炸式增长的时代,传统本地存储因容量限制、管理复杂等问题,已难以满足企业和个人的需求。云存储凭借灵活扩展、便捷访问等特性,成为数据存储领域的主流解决方案。从个人照片备份到企业核心数据管理,云存储正重塑数据存储与…...
