zoukankan      html  css  js  c++  java
  • 性能分析根据进程情况自动抓取内存

    最近我所在项目组的测试服务器的w3wp进程CPU经常接近100%w3wpIIS6及之后版本应用程序池的进程。肯定程序出了问题,但由于一个应用程序池可能挂接多个网站,我们的每个网站几乎都是庞大的代码量,不好定位到底哪里出了问题,并且进程可能不稳定,为了不用一直观察测试服务器w3wp是否正常,我用代码写了一个windows服务,当发现w3wp进程占用cpu达到指定值,就自动抓取对应异常时的w3wp内存dump文件并发送邮件等,方便自己能分析异常时进程的内存dump文件。

     

    一、        原理分析

    本篇文章是介绍在进程占用CPU情况异常时自动抓取内存文件,因此首先需要确定抓取什么进程,进程的PID是多少,然后根据确定的进程,怎么获取进程当前占用CPU情况,根据占用CPU的情况,判断是否发送邮件和抓取内存文件。这里分别用到了获取需要的应用程序池w3wp进程,获取到w3wp进程后,根据性能计数获取占用CPU情况,最后通过adplus抓取内存dump文件,下面分别对几个步骤进行讲解:

    1、获取对应w3wp

    一般一个服务器可能有多个应用程序池,首先应该查看是哪个应用程序池出了问题,从windows任务管理器,所有应用程序池都只是对应同样的名字:w3wp.exe。我们可以通过进程的Pid值,然后运行:iisapp –a,命令查看Pid对应的具体应用程序池名,如图:

     图一

    根据图一,可以看到出问题的w3wp进程对应哪个应用程序池。

    WIN7查看w3wp进程对应哪个应用程序池的方式不一样,以管理员身份在命令行下通过系统盘的windows\system32\inetsrv目录,运行:appcmd.exe list wp,可以查看pid对应的具体应用程序池名,如图:

     图二

    2、获取内存dump文件

    安装windbg后,通过安装目录的adplus.vbs可以抓取内存dump文件,比如装到C:\Program Files\Debugging Tools for Windows (x86)目录下,cd到这个目录,运行:adplus –hang –o D:\dump –p 3152 – quiet,命令的含义是用adplus马上抓取pid3152进程的内存dump文件,保存到D:\dump里。

    3、判断进程占用CPU情况

    通过微软的性能计数提供的API接口,可以比较方便的获取每个进程的占用CPU情况,在System.Diagnostics命名空间下,提供了:PerformanceCounter等性能计数类供调用,该类的NextValue()可以得到当前监控的值。性能监视器,可以从windows下直接运行查看,win7下的界面如下:

     图三

    性能监视主要分3个参数:性能对象,计数器名,实例名(如图三里的Process为性能对象,% Processor Time为计数器,下面的w3wp为实例)。

    首先我们要抓取一个进程的性能对象结果,需要选择Process性能对象,实例名为对应的进程名,但当进程名一样了,内部是以后面加#1,#2,#3等依次递增的数字。因此当我们分析应该抓取哪个w3wp进程来判断进程是否异常时,这里就不好选择实例了。性能计数器当然考虑了这点,选择Process为性能对象,计数器为ID Process时,可以轮训所有的w3wp(和后面加#1,#2,#3)的进程,计算它的PID值,通过原理分析第一步得到我们需要的w3wp进程的PID来比较,如果两个PID相同,则为我们需要的w3wp进程。我实现的代码如:

     图四

    图四省略了其他代码。

    4、整合上面原理123后的实现过程

    a)首先获取所有性能对应为Process的实例列表。

    b)然后通过读取配置的需要监控的应用程序池名,通过程序模拟运行cmd.exe运行iisapp –a(win2003是该命令)后的字符串,用正则表达式找到该应用程序池对应进程的PID值,通过轮训刚才的实例列表,判断实例的PID为我们找到的PID值相等时,说明我们找到了性能对应的实例。

    c)根据找到的性能对象和实例,获取当前的CPU占用值,如果大于配置的值,则抓取内存dump文件和发送邮件。

     

    二、        代码实现

             实现的代码结构如图:

     图五

    把公共代码封装到单独的AutoDumpCore里,可以直接控制台程序AutoDumpTests调用或者windows服务AudoDumpWinService调用。

    注意获取性能对象值,不能每次都实例化性能对象PerformanceCounter,实例化一次就行,当程序自动抓取到的PID不能获取性能对象时,程序再自动重新实例化该性能对象,否则可能获取不到当前进程占用的CPU值。对于自动抓取内存dump文件和发送邮件,当然得控制,不能1分钟前自动抓取和发送了邮件,现在还发送邮件等,内部程序会控制前一个时间点,如果不在配置文件指定的时间范围内,就不自动抓取了。

    由于原理分析得已经比较全面了,代码介绍就省略了,感兴趣的可以看看代码。

     

    转载请注明来自:http://lawson.cnblogs.com/

  • 相关阅读:
    LeetCode -- Rectangle Area
    【转】VS常用快捷键
    C++中include<> 与 include" " 的区别
    浅析_tmain() 与 main() 函数的区别
    VS2013下配置OpenCV 3.0.0 &&& VS2013下配置Opencv2.4.9
    LeetCode -- Valid Parenthese
    杂想 · 警醒
    LeetCode -- Length of Last Word
    LeetCode -- Valid Sudoku
    LeetCode -- Binary Tree Level Order Traversal II
  • 原文地址:https://www.cnblogs.com/Lawson/p/2324055.html
Copyright © 2011-2022 走看看