记一次 .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. 误入歧途

  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 0x00000032c93b7ce02 - dumpobj 0x00000032c93b8ae83 - dumpobj 0x00000032c93b98d8...
54346 - dumpobj 0x00000034d12fb2e8
54347 - dumpobj 0x0000003652805b40
---------------------------------------------
54347 items

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

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

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

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

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

三:总结

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/141927.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

性能测试?

一、什么是性能测试 先看下百度百科对它的定义 性能测试是通过自动化的测试工具模拟多种正常、峰值以及异常负载条件来对系统的各项性能指标进行测试 我们可以认为性能测试是&#xff1a;通过在测试环境下对系统或构件的性能进行探测&#xff0c;用以验证在生产环境下系统性能…

MySQL是如何进行排序的,ORDER BY是如何执行的

MySQL 会给每个线程分配一块内存用于排序&#xff0c;称为 sort_buffer。 假设找出在杭州居住的人&#xff0c;按名字排序前1000个人&#xff08;假设city有索引&#xff0c;那么非常舒服&#xff0c;不用全表扫描&#xff09; select city,name,age from t where city杭州 or…

在qt的设计师界面没有QVTKOpenGLWidget这个类,只有QOpenGLWidget,那么我们如何得到QVTKOpenGLWidget呢?

文章目录 前言不过,时过境迁,QVTKOpenGLWidget用的越来越少,官方推荐使用qvtkopengnativewidget代替QVTKOpenGLWidget 前言 在qt的设计师界面没有QVTKOpenGLWidget这个类,只有QOpenGLWidget,我们要使用QVTKOpenGLWidget,那么我们如何得到QVTKOpenGLWidget呢? 不过,时过境迁,Q…

【ML】欠拟合和过拟合的一些判别和优化方法(吴恩达机器学习笔记)

吴恩达老师的机器学习教程笔记 减少误差的一些方法 获得更多的训练实例——解决高方差尝试减少特征的数量——解决高方差尝试获得更多的特征——解决高偏差尝试增加多项式特征——解决高偏差尝试减少正则化程度 λ——解决高偏差尝试增加正则化程度 λ——解决高方差 什么是…

Zookeeper概述

ZooKeeper概述 1 分布式应用程序2 分布式应用程序的特点3 Apache ZooKeeper简介4 ZooKeeper客户端 - 服务器架构5 ZooKeeper 分层命名空间6 Zookeeper 工作流7 ZooKeeper 选举机制7.1 ZooKeeper选举概述7.1.1 两种情况分析 7.2 选举实现细节 8 FastLeaderElection&#xff1a;选…

Maven 的 spring-boot-maven-plugin 红色报错

1、想要处理此情况&#xff0c;在工具下面加上指定的版本号。 2、给自己的maven的setting文件加工一下。 <mirrors><!--阿里云镜像1--><mirror><id>aliyunId</id><mirrorOf>central</mirrorOf><name>aliyun maven</name>…

数据分析法宝,一个 SQL 语句查询多个异构数据源

随着企业数据量呈现出爆炸式增长&#xff0c;跨部门、跨应用、跨平台的数据交互需求越来越频繁&#xff0c;传统的数据查询方式已经难以满足这些需求。同时&#xff0c;不同数据库系统之间的数据格式、查询语言等都存在差异&#xff0c;直接进行跨库查询十分困难。 原生跨库查…

RabbitMQ 核心部分之简单模式和工作模式

文章目录 一、Hello World&#xff08;简单&#xff09;模式1.导入依赖2.消息生产者3.消息消费者 二、Work Queues&#xff08;工作&#xff09;模式1.抽取工具类2.启动两个工作线程3.启动一个发送线程4.结果 总结 一、Hello World&#xff08;简单&#xff09;模式 在下图中&…

菜单栏管理软件 Bartender 3 mac中文版功能介绍

​Bartender 3 mac是一款菜单栏管理软件&#xff0c;该软件可以将指定的程序图标隐藏起来&#xff0c;需要时呼出即可。 Bartender 3 mac功能介绍 Bartender 3完全支持macOS Sierra和High Sierra。 更新了macOS High Sierra的用户界面 酒吧现在显示在菜单栏中&#xff0c;使其…

基于JavaWeb+SpringBoot+Vue摩托车商城微信小程序系统的设计和实现

基于JavaWebSpringBootVue摩托车商城微信小程序系统的设计和实现 源码传送入口前言主要技术系统设计功能截图Lun文目录订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 源码传送入口 前言 近年来&#xff0c;随着移动互联网的快速发展&#xff0c;电子商务越来越受到…

mysq,数据库的综合查询

记录一下数据库综合查询&#xff0c;复习加深印象 创建教学数据库中包含四个基本表&#xff1a; 教师情况表Teacher&#xff08;Tno 教师号&#xff0c;TName 教师名&#xff0c;TDept 教师所在的院系&#xff09;&#xff1b;课程基本表Course&#xff08;Cno 课号&#xff…

优秀的技术管理者,每天应该做些什么事?

优秀的技术管理者每天应该做些什么事情&#xff1f;这是一个很重要的问题&#xff0c;因为技术管理者的日常工作直接影响着团队的效率和成果。下面我将从几个方面探讨优秀的技术管理者每天应该做些什么事情。 首先&#xff0c;优秀的技术管理者应该关注团队的目标和战略。他们…

设计大咖亲授:Figma中文环境设置全攻略!

作为UI设计师&#xff0c;你一定很熟悉Figma&#xff0c;Figma是一款专注于UI/UX设计的在线协作工具&#xff0c;使用非常高效方便&#xff0c;不需要下载和安装。它只需要通过浏览器编辑&#xff0c;在国外很受欢迎。但是Figma对于国内的小伙伴来说&#xff0c;使用Figma有一定…

优秀智慧园区案例 - 新华三未来工厂制造园,园区业务创新及零碳升级

目录 一、新华三未来工厂制造园建设背景 二、未来工厂制造园总体设计思路 三、未来工厂制造园建设内容 四、关键技术及创新点 五、应用效益与推广 关键词&#xff1a;智慧园区解决方案&#xff0c;智慧园区建设总体方案&#xff0c;智慧园区建设规划方案&#xff0c;智慧园…

GZ038 物联网应用开发赛题第7套

2023年全国职业院校技能大赛 高职组 物联网应用开发 任 务 书 &#xff08;第7套卷&#xff09; 工位号&#xff1a;______________ 第一部分 竞赛须知 一、竞赛要求 1、正确使用工具&#xff0c;操作安全规范&#xff1b; 2、竞赛过程中如有异议&#xff0c;可向现场考评…

SpringBoot文件在线预览实现

kkFileView - 在线文件预览&#xff0c;一款成熟且开源的文件文档在线预览项目解决方案。 详细wiki文档&#xff1a;https://gitee.com/kekingcn/file-online-preview/wikis/pages 中文文档&#xff1a;https://gitee.com/kekingcn/file-online-preview/blob/master/README.md…

Actipro Software WPF Controls 23.1.3

Actipro Software WPF Controls v23.1.3 Actipro Software 为 Microsoft 提供软件组件和 .NET 平台。它位于克利夫兰&#xff0c;重点主要是提供高质量的用户界面软件组件以及客户的过程&#xff0c;以便他们有能力信任&#xff0c;以便为用户应用程序添加强大的功能。自 .NET…

EasyHttp 更新功能 form类型post + 限制次数

场景 easyHttp gitte 很高兴帮到您 点一个star 支持一下作者吧 之前的easyHttp只支持json类型post请求&#xff0c;而且有些接口有限制次数的&#xff0c;在循环调用过程中&#xff0c;容易出现突破限制的情况&#xff0c;现在我们引入了限制次数&#xff0c;例如一分钟6次&…

RT1170的ITM SWO配置,实现printf输出及PC指针的采样分析

最近公司准备启动一个新的项目&#xff0c;使用NXP的MIMXRT1170芯片作为主控&#xff0c;在熟悉芯片的过程中发现RT1176具备ITM和SWO功能模块&#xff0c;于是针对之前项目中因工程庞大导致调试困难的问题&#xff0c;决定使用SWO输出调试信息&#xff0c;这样既可以节省硬件的…

掌握这11点外贸知识,能够给你外贸工作带来很大提升!

01.产品展示 关于产品展示&#xff0c;非常重要也一再提及&#xff0c;一个好的产品必须包括以下几部分&#xff1a; ● 产品标题准确概括产品&#xff1b; ● 产品图片清晰且包括细节图&#xff1b; ● 提供详尽的产品描述&#xff0c;比如型号、尺寸、材质、配件等等。最好…