写在前面

    当管理多台Windows Server服务器时(无论是DB、AD、WEB以及其他的应用服务器),当出现性能或其他问题后,参阅性能计数器都是一个非常好的维度从而推测出问题可能出现的原因,再不济也能缩小需要考虑的问题范围,因此定期收集每一台服务器的计数器就会使得问题有据可循。并且收集到的数据也可以作为BaseLine,即使没有出现问题也可以预先判断一些问题。

    之前看到网上的大多数收集性能计数器的文章都比较局限,一般是只收集单台服务器,因此我分享一个多服务器的写法。

    至于为什么使用PowerShell,因为在微软系产品来说像Python等脚本语言虽然有丰富的开源代码没有太好的对应接口,而PowerShell每一个微软自己的产品都提供了大量的Cmdlet,调用起来甚是方便:-)

 

核心Cmdlet

    获取性能计数器的核心cmdlet就是Get-Counter了,该Get-Counter主要使用两个参数,分别为要获取的计算机名称-ComputerName与性能计数器列表-Counter,这里要注意的是,获取性能计数器需要在被获取服务器有对应权限(Performance Monitor Users组),我这里的例子是使用域管理员帐号收集域内服务器,因此不考虑权限问题。

图1.获取到的远程服务器性能计数器

 

    然后将获取到的结果保存到变量中,如图2所示。

图2.将计数器结果保存到变量中

 

收集多台服务器的多个计数器

    将所需收集的服务器以及所需收集的计数器保存到记事本内,方便随时添加或减少服务器或者计数器,记事本写法如下:

图3.计数器与服务器配置

 

    在PowerShell中使用Get-Content读取配置文件内容,如下:

$currentPath=Split-Path ((Get-Variable MyInvocation -Scope 0).Value).MyCommand.Path

#读取需要收集的性能计数器列表

$ServerNeedScan=get-content $currentPath\ServerNeedScan.txt

$ServerNeedScanArray=$ServerNeedScan.Split(",")

 

 

#读取需要收集的性能计数器

$PerfCounter=get-content $currentPath\PerfmonCounter.txt

$PerfCounterArray=$PerfCounter.Split(",")

代码1.读取服务器列表和计数器列表

现在由于收集的计数器中部分计数器是关于SQL Server的,而部分服务器可能带有实例名称,而对于带有SQL Server实例名称的计数器需要把实例和及其名分开,然后把计数器名称中实例名部分进行替换,代码如下:

foreach ($fcomputer in $ServerNeedScanArray)

{

   

    if($fcomputer.Trim() -eq "")

    {

        continue

    }

    #检查是否为默认实例

    $computer=""

    if($fcomputer -like "*\*")

    {

        $instanceName=$fcomputer.Substring($fcomputer.IndexOf("\")+1,$fcomputer.Length-$fcomputer.IndexOf("\")-1)  

        $computer=$fcomputer.Substring(0,$fcomputer.IndexOf('\'))

    }

    else

    {

        $computer=$fcomputer

        $instanceName=""

    }

 

#遍历所有计数器

    $fullCounter=@()

    foreach($counter in $PerfCounterArray)

    {

        $c=""

        $c+="\"

        $c+=$counter

        $fullCounter+=$c

     }

 

$NoDeaultInstanceName="MSSQL`$"

$NoDeaultInstanceName+=$instanceName

#如果是默认实例

if($instanceName -eq "")

{

   $fullCounter | % { 

   if($_ -like "*network*")

   {

        $finalCounter+= $_.ToLower()

       

   }

   else

   {

       $finalCounter+= $_.ToLower().Replace("*","_total")

   }

   }

}

#如果是非默认实例

else

{

   $a=$fullCounter | % { 

   if($_ -like "*network*")

   {

        $finalCounter+= $_.ToLower().Replace("sqlserver", $NoDeaultInstanceName)

       

   }

   else

   {

        $finalCounter+= $_.ToLower().Replace("*","_total").Replace("sqlserver", $NoDeaultInstanceName)

   }

 

   } 

}

代码2.替换SQL Server计数器中的非默认实例

 

将结果插入一台SQL Server

    上述情况就已经准备好了计数器和服务器名称,现在就可以将这些数据插入到一台集中的SQL Server服务器,代码如下:

$a=(Get-Counter -ComputerName $computer -Counter $finalCounter).CounterSamples |Select-Object Path,CookedValue

 

 

      $InsertSQL=""

      $curentTime=Get-Date

      foreach($PerformanceCounter in $a)

      {

            

          $realvalue=$PerformanceCounter.CookedValue

          $InsertSQL+="INSERT INTO PerfCounter(instancename,event_timestamp,Counter,CounterValue)

              VALUES(''"+$fcomputer+"'',''"+$curentTime+"'',''"+$PerformanceCounter.Path+"'',''"+$realvalue.ToString()+"'');"

          

       

             

       }

      $connectionString3="data source=服务器IP;database=test;uid=perf_writer;pwd=123123;"

      $conn2=new-object system.Data.SqlClient.SqlConnection($connectionString3)

      $conn2.open()

 

      $cmd2=$conn2.CreateCommand()

 

       $cmd2.CommandText=$InsertSQL

       $cmd2.ExecuteNonQuery()

       $conn2.Close()

代码3.读取计数器后插入SQL Server

    现在,读取一台服务器并将计数器记录到数据库中的代码就写好了,并且已经可以灵活配置需要读取的计数器和机器名。

 

多线程读取

    如果需要记录计数器的服务器比较多时,那么循环遍历每一台服务器就会花费比较长的时间,因此需要多线程来加快这一个速度,在PowerShell中,启用多线程的cmdlet是start-job,我们首先需要将代码2和代码3的脚本封装到一个script block中,并设置可传入的参数,如代码4。

$sb = [scriptblock]::Create('

  param($instanceName,$NoDeaultInstanceName,$fullCounter,$fcomputer,$computer)

#这里写其他代码

 

')

 

#开始异步线程,并传入参数

start-job -scriptblock $sb -Argument $instanceName,$NoDeaultInstanceName,$fullCounter,$fcomputer,$computer 

 

代码4.利用异步线程读取计数器数据并插入SQL Server

 

    经过测试,PowerShell对同时可以并发的线程做了限制,这个限制很奇怪,我在每台服务器上测试的结果并不相同,因此如果同时全部并发执行这些线程,某些线程会因为限制而不起作用,因此如果需要记录性能计数器的服务器比较多的话,会丢失一部分服务器信息,我的解决办法是限制同时并发的进程数量,如果进程数量超过规定数值,则等待1秒再次检测,如果检测通过再启动新进程,代码如代码5所示。

While (@(Get-Job | Where { $_.State -eq "Running" }).Count -gt 5) {

        Write-host "Waiting for background jobs..."

        Start-Sleep -Seconds 1

      }

代码5.检测处于“运行中”进程的数量是否大于5

 

定期执行脚本

    现在,上面脚本就可以收集多台服务器的性能计数器,并将结果保存到SQL Server了,现在只需要定期(比如2分钟一次)执行该脚本即可。使用Windows计划任务是定期执行PowerShell脚本推荐的方式,如图4所示。

图4.使用计划任务2分钟收集一次性能计数器信息

 

    在图4中,我们注意到使用了-NonInteractive参数,该参数用于在执行时,不弹出PowerShell窗口。

 

结果

    现在,我们可以看到收集后的性能计数器信息,如图5所示。

图5.收集到的性能计数器信息

 

    有了上述性能计数器信息,我们可以使用一些可视化工具分析这些信息,比如我将数据导入到ElasticSearch中,出几张简单的报表,如图6所示。

图6.使用这些性能计数器出简单的报表

 

    这些报表可以帮助我们直观的看出一些问题,比如图6中的forward record可以看到,某些实例大量缺少聚集索引,或者下面的Top Lock Wait可以看到某些实例定期会产生大量的锁阻塞,从而我们可以更容易提前发现问题,进行解决。

 

小结

    定期收集一些服务器的信息可以帮助在运维工作中掌握主动,在业务中现在流行所谓的“大数据促进决策”,其实在IT运维本身中,收集大量的数据同样重要,通过数据我们甚至可以在问题出现之前发现问题。

    在WIndows下PowerShell无疑是最适合做这一工作的语言。

使用PowerShell收集多台服务器的性能计数器的更多相关文章

  1. logstash+redis收集负载均衡模式下多台服务器的多个web日志

    一.logstash的简介 一般我们看日志来解决问题的时候要么 tail+grep 要么 把日志下载下来再搜索,可以应付不多的主机和应用不多的部署场景.但对于多机多应用部署就不合适了.这里的多机多应用 ...

  2. SQL Server自动化运维系列——关于数据收集(多服务器数据收集和性能监控)

    需求描述 在生产环境中,很多情况下需要采集数据,用以定位问题或者形成基线. 关于SQL Server中的数据采集有着很多种的解决思路,可以采用Trace.Profile.SQLdiag.扩展事件等诸多 ...

  3. 删除HT和CAS角色与扩展在另一台服务器

      背景:原先使用三合一方式部署的架构,如今不再满足企业需求,因此需要将原来的一台服务器多角色的拆分开,即由原来CAS.HT.MBX角色集一台服务器的分成两台服务器来部署,此架构为MBX角色单独部署在 ...

  4. Dynamics 365 for CRM:CRM与ADFS安装到同一台服务器,需修改ADFS服务端口号

    CRM与ADFS安装到同一台服务器时,出现PluginRegistrationTool 及 CRM Outlook Client连接不上,需要修改ADFS的服务端口号,由默认的808修改为809: P ...

  5. zabbix 创建主机、主机群组、监控第一台服务器

    前面介绍了zabbix服务器和zabbix agent的安装配置,今天使用zabbix监控第一台服务器. 1. 安装zabbix agent 在被监控的服务器上安装zabbix agent . 参考& ...

  6. SRV记录用来标识某台服务器使用了某个服务,常见于微软系统的目录管理——深入的话需要去折腾Azure Active Directory

    SRV记录 SRV记录 什么情况下会用到SRV记录? [SRV记录用来标识某台服务器使用了某个服务,常见于微软系统的目录管理] SRV记录的添加方式 A.主机记录处格式为:服务的名字.协议的类型 例如 ...

  7. 搭建jumperserver堡垒机管理万台服务器-1

    搭建jumperserver堡垒机管理万台服务器-1 1  Jumpserver堡垒机概述-部署Jumpserver运行环境 2  安装Coco组件 3  安装Web-Terminal前端-Luna组 ...

  8. Dynamics CRM与ADFS安装到同一台服务器后ADFS服务与Dynamics CRM沙盒服务冲突提示808端口占用问题

    当我们安装Dynamics CRM的产品时如果是单台服务器部署而且部署了IFD的情况会遇到一个问题就是ADFS服务的监听端口和Dynamics CRM沙盒服务的端口冲突了. 这样会导致两个服务中的一个 ...

  9. ElasticSearch 5学习(3)——单台服务器部署多个节点

    一般情况下单台服务器只会部署一个ElasticSearch node,但是在学习过程中,很多情况下会需要实现ElasticSearch的分布式效果,所以需要启动多个节点,但是学习开发环境(不想开多个虚 ...

随机推荐

  1. 【.net 深呼吸】细说CodeDom(7):索引器

    在开始正题之前,先补充一点前面的内容. 在方法中,如果要引用方法参数,前面的示例中,老周使用的是 CodeVariableReferenceExpression 类,它用于引用变量,也适用于引用方法参 ...

  2. 常用 Gulp 插件汇总 —— 基于 Gulp 的前端集成解决方案(三)

    前两篇文章讨论了 Gulp 的安装部署及基本概念,借助于 Gulp 强大的 插件生态 可以完成很多常见的和不常见的任务.本文主要汇总常用的 Gulp 插件及其基本使用,需要读者对 Gulp 有一个基本 ...

  3. SQL Server相关书籍

    SQL Server相关书籍 (排名不分先后) Microsoft SQL Server 企业级平台管理实践 SQL Server 2008数据库技术内幕 SQL Server性能调优实战 SQL S ...

  4. 【资源】.Net 入门@提高 - 逆天的高薪之路!

     入门看视频,提高看书籍,飘升做项目.老练研开源,高手读外文,大牛讲低调~    官方学习计划 http://www.cnblogs.com/dunitian/p/5667901.html ----- ...

  5. Electron使用与学习--(页面间的通信)

    目录结构: index.js是主进程js. const electron = require('electron') const app = electron.app const BrowserWin ...

  6. iOS开发之ReactiveCocoa下的MVVM(干货分享)

    最近工作比较忙,但还是出来更新博客了,今天给大家分享一些ReactiveCocoa以及MVVM的一些东西,干活还是比较足的.在之前发表过一篇博文,名字叫做<iOS开发之浅谈MVVM的架构设计与团 ...

  7. vmware上网的方式

    vmware上网设置 vmware虚拟机上网设置 我的一些心得,如下: 如何使vmware虚拟机中的操作系统能够上网? 第一种情况: 主机使用PPPOE拨号上网 方法一:NAT方式 1.先关闭虚拟机中 ...

  8. UML图中经常用到几种的关系图例

    学习这个东西挺奇怪的,时间一长就容易忘记,或者记不清楚.今天看到一些UML图的关系,发现有些出入了,索性就写下来,以后再忘记的时候过来看看. 在UML的类图中,常见的有以下几种关系: 继承(Gener ...

  9. 使用DeviceOne实现微信小程序功能

    微信小程序即将推出,还没推出就火的不行了.基于微信这个巨大平台,小程序必然能有巨大成功.不过它并不能完全取代App,该开发App还得开发.如果我们自己想实现一个基于自己的APP包含类似微信的小程序功能 ...

  10. 如何搭建git服务器

    一.前言 现在越来越多的公司用git进行版本控制,不过git是默认是开源的,如果私有的话是需要付费的,如果不想付费自己可以搭建一个git服务器用来版本控制. 二.服务器端操作 1.安装git sudo ...