.Net Core服务诊断排查
前言:
近期在项目中出现了几次服务内存资源占用较高的情况,特回顾梳理下排查过程以及对相应问题的排查方法总结。
一、Dump抓取
抓取dump的方式有多种,下面介绍几种常用的:
1. 任务管理器中找到程序进程,右键菜单:创建转存储文件
注意:需要以程序运行的位数运行任务管理器抓取Dump
2. DotNet 全局工具:dotnet-dump;工具可适用于Windows、Linux、macOS平台
a) 安装全局dotnet-dump工具:
dotnet tool install --global dotnet-dump
b) 使用该工具抓取dump:
dotnet-dump collect [-h|--help] [-p|--process-id] [-n|--name] [--type] [-o|--output] [--diag]
-
- -h|--help:显示命令行帮助。
- -p|--process-id <PID>:指定从中收集转储的进程的 ID 号。
- -n|--name <name>:指定从中收集转储的进程的名称。
- --type <Full|Heap|Mini>:指定转储类型,它确定从进程收集的信息的类型。 有三种类型:Full - 最大的转储,包含所有内存(包括模块映像)。Heap - 大型且相对全面的转储,其中包含模块列表、线程列表、所有堆栈、异常信息、句柄信息和除映射图像以外的所有内存。Mini - 小型转储,其中包含模块列表、线程列表、异常信息和所有堆栈。如果未指定,则 Full 为默认类型。
- -o|--output <output_dump_path>:应在其中写入收集的转储的完整路径和文件名。如果未指定:在 Windows 上默认为 .\dump_YYYYMMDD_HHMMSS.dmp ;在 Linux 上默认为 ./core_YYYYMMDD_HHMMSS ;YYYYMMDD 为年/月/日,HHMMSS 为小时/分钟/秒。
- --diag:启用转储收集诊断日志记录。
3、ProcDump抓取Dump工具:自动抓取
命令语法:
procdump.exe [-mm] [-ma] [-mp] [-mc Mask] [-md Callback_DLL] [-mk] [-n Count] [-s Seconds] [-c|-cl CPU_Usage [-u]] [-m|-ml Commit_Usage] [-p|-pl Counter_Threshold] [-h] [-e [1 [-g] [-b]]] [-l] [-t] [-f Include_Filter, ...] [-fx Exclude_Filter, ...] [-o] [-r [1..5] [-a]] [-at Timeout] [-wer] [-64] { {{[-w] Process_Name | Service_Name | PID} [Dump_File | Dump_Folder]} | {-x Dump_Folder Image_File [Argument, ...]} }
参数说明:
警告:高并发值可能会影响系统性能。
- Windows 7:使用反射。 OS 不支持 -e。
- Windows 8.0:使用反射。 OS 不支持 -e。
- Windows 8.1+:使用 PSS。 支持所有触发器类型。 -s 写入转储之前连续秒 (默认值为 10) 。 -t 在进程终止时写入转储。 -u 将 CPU 使用率视为与 -c (一) 。
作为唯一选项,卸载 ProcDump 作为事后调试器。 -w 等待指定的进程启动(如果该进程未运行)。 -wer 将 (最大) 排队到Windows 错误报告。 -x 使用可选参数启动指定的映像。 如果是应用商店应用程序或包,ProcDump 将在下次激活时启动, (激活) 。 -64 默认情况下,在 64 位进程上运行时,ProcDump 将捕获 32 位进程的 32 位Windows。 此选项将替代 以创建 64 位转储。 仅用于 WOW64 子系统调试。 -? 使用 -? -e 查看示例命令行。
示例:
当进程在 5 秒钟内 CPU 使用率超过 50% 时,最多写入 2 个名为"w3wp"的进程的微型转储:
procdump -ma -s 5 -n 2 -c 50 w3wp
二、Dump分析
根据前面几方式得到的Dump文件,下一步就是对Dump进行分析确认问题原因:
1、Windbug Preview 分析:
Windbg Preview 是windows平台上的一款相当强大的调试工具,可以从msdn网站下载得到,最新版本包含在windows sdk中,默认会被安装在C:\Program Files\Debugging Tools for Windows 目录中,可以直接把这个目录打包复制到其它机器上使用。
Windbug常用命令:
-
- !analyze -v 自动分析dump
- kv 查看栈回溯
- .ecxr 显示当前异常上下文
- .cxr 切换异常帧上下文
- .exr 显示异常信息
- .frame 设置当前栈帧
- dv 显示当前栈帧局部变量
- dd 显示内存中的数据
- r 查看寄存器
- lmvm 查看模块详细信息
- r 可以显示系统崩溃时的寄存器,和最后的命令状态
- dd 显示当前内存地址,dd 参数:显示参数处的内存
- u 可以显示反汇编的指令
- kb 显示call stack 内容
2、VS分析Dump:
a) 使用VS打开dump文件:
可以看到该dump的基本信息,接下来设置符号文件:
b) 分析Dump中内存情况:调试托管内存
可以看到当前托管资源中内存占用情况,如果有多个dump还可以对比dump中内存增长变化
查看对象内容:
c) 查看当前运行的进程列表:(设置了符号文件后可以查看当前堆栈信息,以及跳转到代码逻辑)
3、dotnet-dump分析:
分析命令:
dotnet-dump analyze <dump_path> [-h|--help] [-c|--command]
SOS命令支持:
soshelp|help
显示所有可用命令
soshelp|help <command>
执行指定的命令。
exit|quit
退出交互模式。
clrstack <arguments>
仅提供托管代码的堆栈跟踪。
clrthreads <arguments>
列出正在运行的托管线程。
dumpasync <arguments>
显示有关垃圾回收堆上异步状态机的信息。
dumpassembly <arguments>
显示有关指定地址处程序集的详细信息。
dumpclass <arguments>
显示有关指定地址处的 EEClass 结构的信息。
dumpdelegate <arguments>
显示有关指定地址处的委托的信息。
dumpdomain <arguments>
显示所有 AppDomain 和指定域中的所有程序集的信息。
dumpheap <arguments>
显示有关垃圾回收堆的信息和有关对象的收集统计信息。
dumpil <arguments>
显示与托管方法关联的 Microsoft 中间语言 (MSIL)。
dumplog <arguments>
将内存中压力日志的内容写入到指定文件。
dumpmd <arguments>
显示有关指定地址处的 MethodDesc 结构的信息。
dumpmodule <arguments>
显示有关指定地址处的模块的信息。
dumpmt <arguments>
显示有关指定地址处的 MethodTable 的信息。
dumpobj <arguments>
显示有关位于指定地址处的对象的信息。
dso|dumpstackobjects <arguments>
显示在当前堆栈的边界内找到的所有托管对象。
eeheap <arguments>
显示有关内部运行时数据结构所使用的进程内存的信息。
finalizequeue <arguments>
显示所有已进行终结注册的对象。
gcroot <arguments>
显示有关对指定地址处的对象的引用(或根)的信息。
gcwhere <arguments>
显示传入参数在 GC 堆中的位置。
ip2md <arguments>
显示 JIT 代码中指定地址处的 MethodDesc 结构。
histclear <arguments>
释放由 hist* 命令系列使用的任何资源。
histinit <arguments>
从保存在调试对象中的压力日志初始化 SOS 结构。
histobj <arguments>
显示与 <arguments> 相关的垃圾回收压力日志重定位。
histobjfind <arguments>
显示在指定地址处引用对象的所有日志项。
histroot <arguments>
显示与指定根的提升和重定位相关的信息。
lm|modules
显示进程中的本机模块。
name2ee <arguments>
显示 <argument> 的 MethodTable 和 EEClass 结构。
pe|printexception <arguments>
显示从 Exception 类派生的 <argument> 的任何对象。
setsymbolserver <arguments>
启用符号服务器支持
syncblk <arguments>
显示 SyncBlock 持有者信息。
threads|setthread <threadid>
设置或显示 SOS 命令的当前线程 ID。
例如:
dotnet-dump analyze "w3wp (2).DMP"
三、案例:
问题现象:xxx服务请求响应耗时较长,导致业务无法正常开展
排查过程:
1、查看内存情况,Oracle连接数量较大
2、查看线程中都为Oracle连接等待:
3、最终确认请求被卡到了Oracle处理
四、总结
1、在排查服务相关问题时,分析dump方式是最直接的方式;而vs方式分析dump是最直接、方便、简单的方式。
2、通过windbug分析dump是最完整的方式
参考:
windbg命令