写在前面

    当管理多台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. Spark踩坑记——Spark Streaming+Kafka

    [TOC] 前言 在WeTest舆情项目中,需要对每天千万级的游戏评论信息进行词频统计,在生产者一端,我们将数据按照每天的拉取时间存入了Kafka当中,而在消费者一端,我们利用了spark strea ...

  2. Win10 IIS本地部署MVC网站时不能运行?

    异常处理汇总-服 务 器 http://www.cnblogs.com/dunitian/p/4522983.html 部署后出现这个错误: 打开文件目录后发现是可以看见目录的,静态页面也是可以打开的 ...

  3. SQL必备知识点

    经典SQL语句大全 基础 1.说明:创建数据库.说明:删除数据库drop database dbname3.说明:备份sql server--- 创建 备份数据的 device.说明:创建新表crea ...

  4. 【翻译】Awesome R资源大全中文版来了,全球最火的R工具包一网打尽,超过300+工具,还在等什么?

    0.前言 虽然很早就知道R被微软收购,也很早知道R在统计分析处理方面很强大,开始一直没有行动过...直到 直到12月初在微软技术大会,看到我软的工程师演示R的使用,我就震惊了,然后最近在网上到处了解和 ...

  5. MySQL中interactive_timeout和wait_timeout的区别

    在用mysql客户端对数据库进行操作时,打开终端窗口,如果一段时间没有操作,再次操作时,常常会报如下错误: ERROR (HY000): Lost connection to MySQL server ...

  6. 玩转spring boot——结合jQuery和AngularJs

    在上篇的基础上 准备工作: 修改pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=&q ...

  7. (一)开篇—杂谈WebGIS

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.前言 我相信大家对百度地图,谷歌地图等相关应用已经是非常熟悉了.通过 ...

  8. [开发笔记]GCC 分支预测优化

    #define likely(x) __builtin_expect(!!(x),1)#define unlikely(x) __builtin_expect(!!(x),0) 用于优化在做分支判断的 ...

  9. Apache Cordova开发Android应用程序——番外篇

    很多天之前就安装了visual studio community 2015,今天闲着么事想试一下Apache Cordova,用它来开发跨平台App.在这之前需要配置N多东西,这里找到了一篇MS官方文 ...

  10. sql server 取文件名函数 转载

    /****** Object: UserDefinedFunction [dbo].[GetDirectoryPath] Script Date: 2016-12-16 16:54:05 ****** ...