使用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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...