一:背景

1. 讲故事

这段时间经常有朋友微信上问我这个真实案例分析连载怎么不往下续了,关注我的朋友应该知道,我近二个月在研究 SQLSERVER,也写了十多篇文章,为什么要研究这东西呢? 是因为在 dump 中发现有不少的问题是 SQLSERVER 端产生的,比如:遗留事务索引缺失 ,这让我产生了非常大的兴趣,毕竟他们是一对黄金搭档。

回到本话题上来,年前有位朋友找到我,说他的程序在业务高峰期的时候CPU一直居高不下,咨询一下是什么问题? 按照老规矩,上 WinDbg 说话。

二:WinDbg 分析

1. CPU 真的爆高吗

拿到dump之后一定要用数据说话,有时候口头描述会给你带偏,这里用 !tp 验证一下。


0:043> !tp
CPU utilization: 91%
Worker Thread: Total: 11 Running: 4 Idle: 0 MaxLimit: 8191 MinLimit: 4
Work Request in Queue: 1756
Unknown Function: 72179e93 Context: 2104b3a4
Unknown Function: 72179e93 Context: 204230c8
Unknown Function: 72179e93 Context: 210523dc
Unknown Function: 72179e93 Context: 20f13224
Unknown Function: 72179e93 Context: 204110ac
Unknown Function: 72179e93 Context: 2042e0a4
Unknown Function: 72179e93 Context: 204310bc
Unknown Function: 72179e93 Context: 204320c4
Unknown Function: 72179e93 Context: 2042f0b0
...
Unknown Function: 72179e93 Context: 2110a364
Unknown Function: 72179e93 Context: 20e882e8
Unknown Function: 72179e93 Context: 20e91330
--------------------------------------
Number of Timers: 0
--------------------------------------
Completion Port Thread:Total: 2 Free: 2 MaxFree: 8 CurrentLimit: 2 MaxLimit: 1000 MinLimit: 4

这一看吓一跳,在CPU符合预期之外,线程池队列居然累计了高达 1756 个任务未被及时处理,造成这种现象一般有两种情况,要么是线程卡死了,要么是负载过大,相对来说前者居多。

2. 线程都被卡住了吗?

有了这个思路之后,接下来可以用 ~*e !clrstack 观察下所有线程栈是不是有什么东西卡住他们了。


0:043> ~*e !clrstack
OS Thread Id: 0x53c4 (0)
...
OS Thread Id: 0x4124 (42)
Child SP IP Call Site
218acdd8 700facce System.Threading.Tasks.Task.set_CapturedContext(System.Threading.ExecutionContext) [f:\dd\ndp\clr\src\BCL\system\threading\Tasks\Task.cs @ 1779]
218acde8 7094fe81 System.Threading.Tasks.Task`1[[System.__Canon, mscorlib]]..ctor(System.Func`1<System.__Canon>) [f:\dd\ndp\clr\src\BCL\system\threading\Tasks\Future.cs @ 142]
...
OS Thread Id: 0x5be8 (43)
Child SP IP Call Site
2192c820 7746c03c [InlinedCallFrame: 2192c820]
2192c81c 6f47adbc DomainNeutralILStubClass.IL_STUB_PInvoke(IntPtr, Byte*, Int32, System.Net.Sockets.SocketFlags)
2192c820 6f417230 [InlinedCallFrame: 2192c820] System.Net.UnsafeNclNativeMethods+OSSOCK.recv(IntPtr, Byte*, Int32, System.Net.Sockets.SocketFlags)
...
OS Thread Id: 0x4b70 (47)
Child SP IP Call Site
1abedaec 7746c03c [InlinedCallFrame: 1abedaec]
1abedae8 6f47adbc DomainNeutralILStubClass.IL_STUB_PInvoke(IntPtr, Byte*, Int32, System.Net.Sockets.SocketFlags)
1abedaec 6f417230 [InlinedCallFrame: 1abedaec] System.Net.UnsafeNclNativeMethods+OSSOCK.recv(IntPtr, Byte*, Int32, System.Net.Sockets.SocketFlags)
1abedb24 6f417230 System.Net.Sockets.Socket.Receive(Byte[], Int32, Int32, System.Net.Sockets.SocketFlags, System.Net.Sockets.SocketError ByRef) [f:\dd\NDP\fx\src\net\System\Net\Sockets\Socket.cs @ 1780]
1abedb54 6f416fdf System.Net.Sockets.Socket.Receive(Byte[], Int32, Int32, System.Net.Sockets.SocketFlags) [f:\dd\NDP\fx\src\net\System\Net\Sockets\Socket.cs @ 1741]
1abedb78 6f415e64 System.Net.Sockets.NetworkStream.Read(Byte[], Int32, Int32) [f:\dd\NDP\fx\src\net\System\Net\Sockets\NetworkStream.cs @ 508]
1abedba8 701150ec System.IO.BufferedStream.ReadByte() [f:\dd\ndp\clr\src\BCL\system\io\bufferedstream.cs @ 814]
...

仔细观察这些线程栈发现大多请求都在网络IO上,并没有什么卡死的情况,所以这条路基本上就走不通了。

3. 是负载过大吗?

如果要从这条路往下走该怎么处理呢?首先看下 CPU 强不强,可以用 !cpuid 命令探究下。


0:043> !cpuid
CP F/M/S Manufacturer MHz
0 6,63,2 GenuineIntel 2394
1 6,63,2 GenuineIntel 2394
2 6,63,2 GenuineIntel 2394
3 6,63,2 GenuineIntel 2394

我去,堂堂一个Web服务器就这点配置真的有点太省了,看样子还真是请求过多线程处理不及,接下来的问题是怎么看请求是否过多呢?可以到托管堆中去找 HttpContext 对象,因为它封装了承接后的 web 请求,这里使用 !whttp 命令观察即可。


0:043> !whttp
Starting indexing at 10:24:39
1000000 objects...
2000000 objects...
Indexing finished at 10:24:42
423,973,906 Bytes in 2,535,718 Objects
Index took 00:00:02
HttpContext Thread Time Out Running Status Verb Url
02924904 -- 00:01:50 00:00:08 200 GET http://xxx?Ids=[xxx,xxx]
...
2793343c -- 00:01:50 Finished 200 GET http://xxx?Ids=[xxx,xxx]
27a67c30 -- 00:01:50 Finished 200 GET http://xxx?Ids=[xxx,xxx]
27a85568 -- 00:01:50 Finished 200 GET http://xxx?Ids=[xxx,xxx]
27aab224 -- 00:01:50 Finished 200 GET http://xxx?Ids=[xxx,xxx]
27b08de4 -- 00:01:50 Finished 200 GET http://xxx?Ids=[xxx,xxx]
27b4ab60 -- 00:01:50 00:00:08 200 GET http://xxx?Ids=[xxx,xxx]
...
3543e0bc 37 00:01:50 00:00:00 200 GET http://xxx?Ids=[xxx,xxx] 1,197 HttpContext object(s) found matching criteria You may also be interested in
================================
Dump HttpRuntime info: !wruntime

这一看又吓一跳,托管堆上 1197 个 HttpContext,几乎都是 http://xxx?Ids=[xxx,xxx] 请求,截图如下:

我相信线程池队列中排队的 1756 个请求应该几乎也是 http://xxx?Ids=[xxx,xxx],这一前一后加起来有 3000 左右的并发请求,哈哈,3000 大军把 CPU 按在地上摩擦。

4. 寻找问题方法

有了请求之后就可以寻找对应的处理方法,为了保密这里就不细说了,方法有很多的逻辑,对外还涉及到了 Redis,ES 等第三方组件,看样子这方法并发度并不高,也难怪并发高了CPU处理不及。

接下来就是建议朋友优化这个方法,能缓存的就缓存,根据朋友反馈整体改动后效果不好,采用了其他的预生成措施解决了这个问题,观察后 CPU 也正常了。

三:总结

这个 dump 还是蛮有意思的,真的是属于请求过载导致的 CPU 爆高,解决办法也有很多:

  • 纵向扩展,增加 CPU。
  • 横向扩展,增加机器。
  • 预计算,根据业务来

记一次 .NET 某游戏网站 CPU爆高分析的更多相关文章

  1. 记一次 .NET 车联网云端服务 CPU爆高分析

    一:背景 1. 讲故事 前几天有位朋友wx求助,它的程序CPU经常飙满,没找到原因,希望帮忙看一下. 这些天连续接到几个cpu爆高的dump,都看烦了,希望后面再来几个其他方面的dump,从沟通上看, ...

  2. 记一次 .NET 差旅管理后台 CPU 爆高分析

    一:背景 1. 讲故事 前段时间有位朋友在微信上找到我,说他的 web 系统 cpu 运行一段时候后就爆高了,让我帮忙看一下是怎么回事,那就看吧,声明一下,我看 dump 是免费的,主要是锤炼自己技术 ...

  3. 记一次 .NET 某电子病历 CPU 爆高分析

    一:背景 1.讲故事 前段时间有位朋友微信找到我,说他的程序出现了 CPU 爆高,帮忙看下程序到底出了什么情况?图就不上了,我们直接进入主题. 二:WinDbg 分析 1. CPU 真的爆高吗? 要确 ...

  4. 记一次 .NET 某安全生产信息系统 CPU爆高分析

    一:背景 1.讲故事 今天是的第四天,头终于不巨疼了,写文章已经没什么问题,赶紧爬起来写. 这个月初有位朋友找到我,说他的程序出现了CPU爆高,让我帮忙看下怎么回事,简单分析了下有两点比较有意思. 这 ...

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

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

  6. 记一次 .NET 某电商交易平台Web站 CPU爆高分析

    一:背景 1. 讲故事 已经连续写了几篇关于内存暴涨的真实案例,有点麻木了,这篇换个口味,分享一个 CPU爆高 的案例,前段时间有位朋友在 wx 上找到我,说他的一个老项目经常收到 CPU > ...

  7. 记一次 .NET 某机械臂智能机器人控制系统MRS CPU爆高分析

    一:背景 1. 讲故事 这是6月中旬一位朋友加wx求助dump的故事,他的程序 cpu爆高UI卡死,问如何解决,截图如下: 在拿到这个dump后,我发现这是一个关于机械臂的MRS程序,哈哈,在机械臂这 ...

  8. 记一次 .NET游戏站程序的 CPU 爆高分析

    一:背景 1. 讲故事 上个月有个老朋友找到我,说他的站点晚高峰 CPU 会突然爆高,发了两份 dump 文件过来,如下图: 又是经典的 CPU 爆高问题,到目前为止,对这种我还是有一些经验可循的. ...

  9. 记一次 .NET 某供应链WEB网站 CPU 爆高事故分析

    一:背景 1. 讲故事 年前有位朋友加微信求助,说他的程序出现了偶发性CPU爆高,寻求如何解决,截图如下: 我建议朋友用 procdump 在 cpu 高的时候连抓两个dump,这样分析起来比较稳健, ...

  10. 记一次 .NET 某医院HIS系统 CPU爆高分析

    一:背景 1. 讲故事 前几天有位朋友加 wx 抱怨他的程序在高峰期总是莫名其妙的cpu爆高,求助如何分析? 和这位朋友沟通下来,据说这问题困扰了他们几年,还请了微软的工程师过来解决,无疾而终,应该还 ...

随机推荐

  1. 【初赛】CSP 2020 第一轮(初赛)模拟记录

    感觉初赛不过关,洛谷上找了一套没做过的来练习. 顺便写了详细的题解. 试题用时:1h 单项选择: 第 1 题 十进制数 114 的相反数的 8 位二进制补码是: A.10001110 B.100011 ...

  2. 更换K8S证书可用期

    帮助文档:https://zealous-cricket-cfa.notion.site/kubeadm-k8s-24611be9607c4b3193012de58860535e 解决: 1.安装GO ...

  3. RSA、DSA 和 ECC 加密算法有什么区别?

    RSA.DSA 和 ECC 加密算法是用于在公钥基础设施中生成密钥的主要算法. 公钥基础设施 (PKI) 用于管理互联网通信和计算机网络中的身份和安全性. 启用 PKI 的核心技术是公钥密码术,这是一 ...

  4. ATM项目详解

    内容概要: ATM项目 代码实操流程 ATM项目 # 需求: """ - 额度15000或自定义 - 支持多账户登录 - 可以查看账户余额 - 可以提现(可自定义手续费比 ...

  5. 程序员面试干货:漫谈计算机网络:数据链路层 ----- 数据链路路在何方? --从点对点数据传输 到 "广泛撒网,重点捕获"的局域网

    面试答不上?计网很枯燥? 听说你学习 计网 每次记了都会忘? 不妨抽时间和我一起多学学它 深入浅出,用你的空闲时间来探索计算机网络的硬核知识! 博主的上篇连载文章<初识图像处理技术> 图像 ...

  6. 【Hadoop学习】下:MapReduce程序编写、Hadoop序列化、框架原理、Yarn组件、设置队列

    一.MapReduce概述 1.定义 编程框架,组成分布式运算程序,运行在集群上 2.特点 优点:易于编程.扩展性.容错性(内部完成).海量数据离线处理 缺点:非实时.不擅长流式计算.不擅长DAG有向 ...

  7. 【大数据面试】【框架】kafka:组成、台数/参数配置、持久化、ISR队列、宕机、丢数据、重复数据、数据积压、优化各种配置(刷盘、存盘、副本、压缩)、zk、其他

    一.基本信息 1.组成 生产者 broker 消费者 zookeeper:brokerid.consumer信息(不包含生产者的信息) 2.需要安装多少台 2 * (生产者的峰值生产速率 * 副本 / ...

  8. python3中的常见知识点3------reduce()函数

    python3中的常见知识点3--reduce()函数 python3导入reduce()函数 reduce()函数语法 reduce()举例 其他python3常用函数 参考链接 python3中不 ...

  9. 分享一个你很可能不知道的Java异常实现的缺陷

    前言 Java中一个大家熟知的知识点就是异常捕获,try...catch...finally组合,但是很多人不知道这里面有一个关于Java的缺陷,或者说是异常实现的一点不足之处. 我这边就通过一个很简 ...

  10. 0停机迁移Nacos?Java字节码技术来帮忙

    摘要:本文介绍如何将Spring Cloud应用从开源Consul无缝迁移至华为云Nacos. 本文分享自华为云社区<0停机迁移Nacos?Java字节码技术来帮忙>,作者:华为云PaaS ...