KK体育备用注册
  咨询电话:15596121183

KK集团备用注册

WinDbg调试分析 asp.net站点 CPU100%问题

      公司为了节省成本,最近有一批服务器降了配置,CPU从8核降到了2核。本身是小站点,访问量也不高,CPU总是会飙到100%而且可以一直持续几个小时,直接强制结束进程可以维持几个小时,几个小时后又一样,运维那边总是受到cpu的警告短信很是苦恼,按理来说就算降低了配置也不至于会让CPU一直100%。 

  以下就分享本次使用 WinDbg 找出 CPU 100% 问题的经验:

  1.创建Dump文件

    

 

  进程注意是32位的,还是64位。64位的进程可以直接创建,32位进程请使用C:WindowsSysWOW64askmgr.exe 任务管理器进行创建,否则放到windbg中会报错。

  2.用windbg载入dump文件

  32位的进程使用x86的windbg加载,64为的进程使用x64的windbg来加载。下载地址https://github.com/LonelyCodelang/Tools/tree/master/Windbg_x86_x64

  

  3.配置调试环境

打开后,会显示程序当时运行所在的环境,此时,会提示符号文件没有发现:

*** ERROR: Symbol file could not be found. Defaulted to export symbols for ntdll.dll -

如果不配置,使用命令的时候会提示错误,比如:

0:000> .loadby sos clrjit0:000> !tp*** ERROR: Symbol file could not be found. Defaulted to export symbols for clr.dll - ************* Symbol Loading Error Summary **************Module name Errorclr PDB not found : e:appserversymbolsdllclr.pdb

e:appserver 是我的dmp文件所在的目录,它默认是到symbols 子目录去找符号文件去了。

然后,配置下使用此文件的调试环境。在菜单命令 File->Symbol path... 打开对话框,选择浏览,找到dmp文件所在目录相关的程序文件目录 E:AppServer ,该目录下面有程序相关的 exe,pdb 文件。

输入下面的命令:

0:000> .sympath+ c:symbolsSymbol search path is: E:AppServer;c:symbolsExpanded Symbol search path is: e:appserver;c:symbolsError: Attempts to access "c:symbols" failed: 0x2 - 系统找不到指定的文件。************* Symbol Path validation summary **************Response Time (ms) LocationOK E:AppServerError

这里不用管,这个文件夹后面可以生成。

0:000> .symfix0:000> .symfix+ c:symbols0:000> .sympathSymbol search path is: srv*Expanded Symbol search path is: SRV*c:symbols*http://msdl.microsoft.com/download/symbols************* Symbol Path validation summary **************Response Time (ms) LocationDeferred

这下对了。执行下 reload命令:

0:000> .reload............................................................................................................................................

接着执行下面:

0:000> .loadby sos clr0:000> !tpThe version of SOS does not match the version of CLR you are debugging. Pleaseload the matching version of SOS for the version of CLR you are debugging.CLR Version: 4.0.30319.296SOS Version: 4.6.96.0Failed to load data access DLL, 0x80004005

这里提示说SOS的版本更CLR不匹配,这里需要找到当时生成Dump文件所在的服务器上的 sos.dll,注意,因为服务器程序是64位的,所以必须在 .Net Framework64 目录去找,同时把 mscordacwks.dll 文件一起拷贝过来(先暂时不用,下面马上会讲到)。

刚才这个命令执行后,我们惊喜的发现,c:symbols 目录自己创建了,并且下载了 clr.pdb等几个目录,这是再将刚才服务器上拷贝的 sos.dll, mscordacwks.dll ,放到本地机器的 c:symbols 目录下面。

再次执行这几个命令:

0:000> .reload............................................................................................................................................0:000> .loadby sos clr0:000> !tpThe version of SOS does not match the version of CLR you are debugging. Pleaseload the matching version of SOS for the version of CLR you are debugging.CLR Version: 4.0.30319.296SOS Version: 4.6.96.0Failed to load data access DLL, 0x80004005

还是报错,看来 sos.dll 没有加载正确,用下面的命令:

0:000> .load c:symbolssos.dll0:000> .loadby sos clr0:000> !tp

这里load命令必须带SOS.dll的路径。加载了它,然后执行 .loadby sos clr ,表示调试.NET托管程序。

开始漫长的等待,程序窗口提示:

*BUSY*Downloading symbols for [clr.pdb] /

等到相关的符号文件全部下载完毕,终于出现了久违的成功界面:

CPU utilization: 11%Worker Thread: Total: 8 Running: 0 Idle: 8 MaxLimit: 32767 MinLimit: 8Work Request in Queue: 0--------------------------------------Number of Timers: 14--------------------------------------Completion Port Thread:Total: 1 Free: 1 MaxFree: 16 CurrentLimit: 0 MaxLimit: 1000 MinLimit: 8

  4.找出占用CPU最多的Thread,并切换到改Thread 

  使用!runaway 找出每个Thread消耗的cpu时间。下图最耗时的线程ID是17,造成CPU100%的就是此线程。

  

  ~17s

        切换到此线程

   

  5.使用 !clrstack 列出 Thread 27 的 Callstack 

从这里就可以定位到具体的方案,是RabbitMQ消费方法的线程造成的,具体就可以看内部方法的实现,然后进行优化。

 

相关参考文章:

https://blogs.msdn.microsoft.com/tess/2010/09/29/capturing-memory-dumps-for-32-bit-processes-on-an-x64-machine/

https://www.cnblogs.com/bluedoctor/p/4813125.html

https://stackoverflow.com/questions/16422577/sos-does-not-support-the-current-target-architecture/16422887