DotTrace系列:6. 程序异常诊断 和 Request慢处理
一:背景
1. 讲故事
在我分析的众多dump中,有一些CPU爆高是因为高频的抛 Exception 导致,比如下面这张图,有 19 个线程都在抛 xxxResultException
异常。
从卦中虽知大量异常的痕迹,但从严谨的角度来说,最好再卜一卦,就是用 perfview 或者 dottrace 在 cpu 爆高的时段记录下异常的数量,这样就稳了,这篇我们就来解决这个棘手的问题。
二:异常诊断 和 Request慢处理
1. 程序异常诊断
有一个项目平时CPU的利用率都是几个点,突然在某段时间CPU明显升高,高达20多个点,我想知道此时程序在干什么?截图如下:
这种问题除了抓dump,还有一个轻量级的途径就是用 dottrace,开启 timeline 模式跟踪,收集一段时间之后,打开跟踪文件。
从卦中可以看出如下信息:
- 大量的线程池线程正在 Running (灰蓝色)
- Exceptions 事件个数高达 341w。
- 产生异常最多的是 ThrowHighFrequencyException 方法。
- 追踪周期仅为 15s
以上四个信息就能非常确认,程序的CPU爆高就是因为大量抛出异常
所致,接下来选择Filters面板中的 Exceptions
进行下钻观察 异常类型
和 异常消息
的分布,截图如下:
从卦中可以看到 InvalidOperationException
异常抛的是最多的,高达 273w
,并且还是定位在 ThrowHighFrequencyException 方中,接下来对父子方法 Show Code
,代码参考如下:
private static void WorkerThreadProc()
{
Random random = new Random(Thread.CurrentThread.ManagedThreadId);
while (running)
{
try
{
// 80%概率抛出高频异常,20%概率抛出其他异常
if (random.Next(100) < 80)
{
ThrowHighFrequencyException();
}
else
{
ThrowLowFrequencyException(random);
}
}
catch (InvalidOperationException)
{
Interlocked.Increment(ref highFrequencyExceptions);
Interlocked.Increment(ref totalExceptions);
}
catch
{
Interlocked.Increment(ref totalExceptions);
}
}
}
// 高频异常方法
private static void ThrowHighFrequencyException()
{
throw new InvalidOperationException("高频异常:无效操作");
}
到此问题真相大白,有些朋友可能想知道每个异常发生的时点
,这就需要你放大 时间轴
了哈,图中的黑色便是。
还有一种方式就是打开 Event 面板 View -> Events
,然后观察左侧的偏移时间(Timestamp),非常清楚加明细,截图如下:
2. Request慢处理
在给web程序做性能优化时,经常要做的一件事情就是查找慢请求
,这也是 dotrace 的强项,它用一个 Incoming HTTP Requests
提供了独家支持,刚好手里有一个 dtp 文件,直接打开。
从卦中可以看到当前程序涉及到的 http 请求总时间为 12s
,那 12s 都被哪些request 请求分摊着呢? 继续下钻即可,选择 Incoming HTTP Requests
,截图如下:
从卦中可以看到当前 WeatherForecast/slow-random
累计时间是最高的,其次是 WeatherForecast/slow-fixed
,这里有一个误区,累计时间最高不见得单次时间就高,这是一个很显然的道理。
接下来观察下 WeatherForecast/slow-random
请求的分布情况,观察时间轴可知有两次请求,截图如下:
接下来的问题是这两个请求来自于哪两个方法呢?选中一个时间稍微长的,放大时间轴之后,点击 Plain List
观察 Total Time 最高的一列即可,截图如下:
最后就是 Show Code 观察 GetWithRandomDelay
方法的源代码,参考如下:
// 2. 随机慢速接口 - 延迟2-5秒随机
[HttpGet("slow-random")]
public async Task<IEnumerable<WeatherForecast>> GetWithRandomDelay()
{
// 随机等待2-5秒
var delay = Random.Shared.Next(2000, 5000);
await Task.Delay(delay);
return GenerateRandomForecasts(5);
}
// 辅助方法:生成随机天气预报数据
private IEnumerable<WeatherForecast> GenerateRandomForecasts(int count)
{
return Enumerable.Range(1, count).Select(index => new WeatherForecast
{
Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
});
}
当然其他接口的调查也可以参考同样的方式。
三:总结
dotrace 非常强大,在观测 异常
和 慢Request
处理方面表现优秀,作为一位 .NET高级调试分析师
,这款工具不可或缺!
作为JetBrains社区内容合作者,如有购买jetbrains的产品,可以用我的折扣码 HUANGXINCHENG,有25%的内部优惠哦。
DotTrace系列:6. 程序异常诊断 和 Request慢处理的更多相关文章
- Java基础进阶:时间类要点摘要,时间Date类实现格式化与解析源码实现详解,LocalDateTime时间类格式化与解析源码实现详解,Period,Duration获取时间间隔与源码实现,程序异常解析与处理方式
要点摘要 课堂笔记 日期相关 JDK7 日期类-Date 概述 表示一个时间点对象,这个时间点是以1970年1月1日为参考点; 作用 可以通过该类的对象,表示一个时间,并面向对象操作时间; 构造方法 ...
- C# 程序异常管理方案
C# 程序异常管理方案 1.程序出现未处理异常(程序中未捕获异常.添加异常处理) 2.程序添加全局异常捕获 tip:程序已处理异常不在捕获范围内. /// <summary> /// 应用 ...
- AIX系统程序异常不释放光驱处理
AIX操作系统有时会出现程序异常不释放光驱,可以用以下命令进行处理: #fuser -kxuc /dev/cd0 或者 #fuser /dev/cd0 以上命令会列出访问光驱设备的所有进程,然后使用k ...
- 调试技巧 —— 如何利用windbg + dump + map分析程序异常
调试技巧 —— 如何利用windbg + dump + map分析程序异常 逗比汪星人2011-09-04上传 调试技巧 —— 如何利用windbg + dump + map分析程序异常 http ...
- android捕获程序异常退出
今天看到迅雷动漫里面一个CrashHandler 的类,我猜是崩溃处理类.进去一看.果然.顺便学习一下. Android系统的"程序异常退出",给应用的用户体验造成不良影响.为了捕 ...
- Android系统的“程序异常退出”[转]
在应用运行过程中,有很多异常可能会发生,而我们希望在异常发生的时候第一时间的保存现场. 如何处理未捕获的异常呢? 首先我们要实现一个接口 java.lang.Thread.UncaughtExcep ...
- 在程序异常中记录堆栈信息(使用ExWatcher)
在我们编写程序的时候可通过IDE自带的调试环境捕捉到异常(Except)错误,并能查看到相关的信息以便我们修正程序中的问题.但当软件被发布出去后,因为所部署运行的环境与我们的调试环境有很大区别,即使在 ...
- 【转载】 ISO14229系列之二:诊断指令格式和相关概念
转载链接:http://www.cnblogs.com/autogeek/p/4458658.html 1. 简单的通信机制 其实诊断通信的机制很简单,可以类比client-server通信方式,即客 ...
- 【微信小程序】调用wx.request接口需要注意的问题
写在前面 之前写了一篇<微信小程序实现各种特效实例>,上次的小程序的项目我负责大部分前端后台接口的对接,然后学长帮我改了一些问题.总的来说,收获了不少吧! 现在项目已经完成,还是要陆陆续续 ...
- 【小程序】调用wx.request接口时需要注意的问题
写在前面 之前写了一篇<微信小程序实现各种特效实例>,上次的小程序的项目我负责大部分前端后台接口的对接,然后学长帮我改了一些问题.总的来说,收获了不少吧! 现在项目已经完成,还是要陆陆续续 ...
随机推荐
- 什么是RESTful 或 GraphQL?
RESTful 与 GraphQL 深度解析 在前端的开发过程中,相信 everyone 对 Get.POST 等请求方式都很熟悉,那么这些请求是归于哪种架构或者设计风格可能又不是很熟.现在在这简单的 ...
- 帮客户解决基于surging的物流速运网关内存泄漏问题
一.概述 有surging企业客户找到我,系统已经在线上环境运行,在使用过程中碰到内存不能释放的问题,每次都要和客户打招呼进行重启造成很坏的影响,问能不能彻底解决掉,然后我打包票可以解决,解决不了不收 ...
- Greenplum数据库索引解析
以下是对greenplum数据库使用总结. 创建索引 CREATE INDEX i_test_tb_state_az ON test_tb(name_en) WHERE name_en = 'AZ'; ...
- 使用Python建模量子隧穿
引言 量子隧穿是量子力学中的一个非常有趣且令人神往的现象.在经典物理学中,我们通常认为粒子必须克服一个势垒才能通过它.但是,在量子力学中,粒子有时可以"穿越"一个势垒,即使它的能量 ...
- Spring框架中的单例bean是线程安全的吗?
1.介绍两个概念 有状态的bean:对象中有实例变量(成员变量),可以保存数据,是非线程安全的 无状态的bean:对象中没有实例变量(成员变量),不能保存数据,可以在多线程环境下共享,是线程安全的 2 ...
- 线上救急-AWS限频
线上救急-AWS限频 问题 在一个天气炎热的下午,我正喝着可口可乐,悠闲地看着Cursor生成代码,忽然各大群聊中出现了加急@全体的消息,当时就心里一咯噔,点开一看,果然,线上服务出问题,多个能源统计 ...
- .net6 api添加接口注释
参照: .NET 6 Swagger添加xml注释 - 凡尘一叶~ - 博客园 (cnblogs.com)[这个比较准] .net core的Swagger接口文档使用教程(一):Swashbuckl ...
- 通用型产品发布解决方案(SpringBoot+SpringCloud+Spring CloudAlibaba+Vue+ElementUI+MyBatis-Plus+MySQL+Git+Maven)03
通用型产品发布解决方案(基于分布式微服务技术栈:SpringBoot+SpringCloud+Spring CloudAlibaba+Vue+ElementUI+MyBatis-Plus+MySQL+ ...
- 【记录】smartctl|Linux如何通过smartctl查看有没有坏的磁盘?以及使用时长、电源周期、故障记录等
smartctl是一个用于监测和分析硬盘健康状态的工具,可以用于检测是否存在坏的磁盘.以下是使用smartctl检查磁盘健康状态的步骤: 安装smartctl软件 在Linux系统中,smartc ...
- python简单的time ticker
在某些时候,我们需要精确的启动一个func,如果用time.sleep简单的轮询,会因为执行的任务阻塞,或者其他原因导致无法精确的定时执行. 例如在采集某些数据的时候,需要精确的每60秒采集一次,如果 ...