使用PowerShell收集多台伺服器的性能計數器

来源:http://www.cnblogs.com/CareySon/archive/2016/09/06/Collect_perfmonCounter_using_PowerShell.html
-Advertisement-
Play Games

寫在前面 當管理多台Windows Server伺服器時(無論是DB、AD、WEB以及其他的應用伺服器),當出現性能或其他問題後,參閱性能計數器都是一個非常好的維度從而推測出問題可能出現的原因,再不濟也能縮小需要考慮的問題範圍,因此定期收集每一臺伺服器的計數器就會使得問題有據可循。並且收集到的數據也 ...


寫在前面

    當管理多台Windows Server伺服器時(無論是DB、AD、WEB以及其他的應用伺服器),當出現性能或其他問題後,參閱性能計數器都是一個非常好的維度從而推測出問題可能出現的原因,再不濟也能縮小需要考慮的問題範圍,因此定期收集每一臺伺服器的計數器就會使得問題有據可循。並且收集到的數據也可以作為BaseLine,即使沒有出現問題也可以預先判斷一些問題。

    之前看到網上的大多數收集性能計數器的文章都比較局限,一般是只收集單台伺服器,因此我分享一個多伺服器的寫法。

    至於為什麼使用PowerShell,因為在微軟系產品來說像Python等腳本語言雖然有豐富的開源代碼沒有太好的對應介面,而PowerShell每一個微軟自己的產品都提供了大量的Cmdlet,調用起來甚是方便:-)

 

核心Cmdlet

    獲取性能計數器的核心cmdlet就是Get-Counter了,該Get-Counter主要使用兩個參數,分別為要獲取的電腦名稱-ComputerName與性能計數器列表-Counter,這裡要註意的是,獲取性能計數器需要在被獲取伺服器有對應許可權(Performance Monitor Users組),我這裡的例子是使用域管理員帳號收集域內伺服器,因此不考慮許可權問題。

image

圖1.獲取到的遠程伺服器性能計數器

 

    然後將獲取到的結果保存到變數中,如圖2所示。

image

圖2.將計數器結果保存到變數中

 

收集多台伺服器的多個計數器

    將所需收集的伺服器以及所需收集的計數器保存到記事本內,方便隨時添加或減少伺服器或者計數器,記事本寫法如下:

image

圖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所示。

image

圖4.使用計劃任務2分鐘收集一次性能計數器信息

 

    在圖4中,我們註意到使用了-NonInteractive參數,該參數用於在執行時,不彈出PowerShell視窗。

 

結果

    現在,我們可以看到收集後的性能計數器信息,如圖5所示。

image

圖5.收集到的性能計數器信息

 

    有了上述性能計數器信息,我們可以使用一些可視化工具分析這些信息,比如我將數據導入到ElasticSearch中,出幾張簡單的報表,如圖6所示。

image

圖6.使用這些性能計數器出簡單的報表

 

    這些報表可以幫助我們直觀的看出一些問題,比如圖6中的forward record可以看到,某些實例大量缺少聚集索引,或者下麵的Top Lock Wait可以看到某些實例定期會產生大量的鎖阻塞,從而我們可以更容易提前發現問題,進行解決。

 

小結

    定期收集一

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 最近在使用mybatis,然後用到了小於等於,直接在XML中使用了 sum(case when p.pool_year 猜想可能是由於特殊字元的緣故,於是用了轉義字元進行了替換了,如下: sum(case when p.pool_year <= '2014' then p.pool_rmb e ...
  • 說到資料庫,我們首先要瞭解的應該是它的歷史或者說前身。細緻的說,資料庫的發展主要經歷了三個階段:1、人工管理階段 2、文件系統階段 3、資料庫系統階段。如何來理解呢?實質上,資料庫,顧名思義,就是管理數據的倉庫。那麼顯然,這不是一個真實的倉庫,而只是一個電子倉庫。為什麼我們要有這麼一個電子的倉庫呢? ...
  • 一:Oracle11g的安裝過程(Windows版本)很簡單,步驟為: 1. 首先從Oracle官方網站上下載Oracle11g資料庫,大約為1.7G。解壓後,setup.ext就可以開始安裝 2. 在安裝開始的時候,會要求填寫一些信息。需要註意兩項: 1)SID。這應該是安裝的資料庫的Servic ...
  • 備份資料庫(進入Mysql bin目錄下) 備份表結構及數據 mysqldump -hlocalhost -uroot -proot db_dev>d:\db_dev.sql 備份表結構 mysqldump -hlocalhost -uroot -proot -d db_dev>d:\db_dev. ...
  • 最近在抓取一些社交網站的數據,抓下來的數據用MySql存儲。問我為什麼用MySql,那自然是入門簡單,並且我當時只熟悉MySql。可是,隨著數據量越來越大,有一個問題始終困擾著我,那就是 社交關係的存儲 。 就以新浪微博舉例,一個大V少則十幾萬,多則幾千萬的粉絲,這些關註關係要怎麼存呢?在MySql ...
  • SQL 程式中SQL執行的結果返回的是DataFrame, DataFrames DataFrames是分散式數據集,由帶名字的列組成。類似關係型資料庫的結構。 DataFrames的數據來源包括:結構化數據文件,Hive表,RDDs,外部資料庫;結構化數據文件包括json,parquet. Dat ...
  • 1.log_timestamps 在5.7.2以後的版本中增加一個單獨控制error log , general log,slow log的記錄的時間,預設是UTC,需要配置成SYSTEM(本地時間)否則用的是UTC的時間。 ...
  • CentOS7預設資料庫是mariadb,配置等用著不習慣,因此決定改成mysql,但是CentOS7的yum源中預設好像是沒有mysql的。為瞭解決這個問題,我們要先下載mysql的repo源。 1.下載mysql的repo源 2.安裝mysql-community-release-el7-5.n ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...