Windows Server Performans Analizi: Performans Sayaçları

Bir Windows Server’ın neden yavaşladığını bulmaya çalışmak, bazen karanlıkta el yordamıyla bir şeyler aramak gibi hissettiriyor. Sunucu çöküyor, kullanıcılar şikayet ediyor, yöneticiler seni arıyor ve sen hâlâ sorunun nereden kaynaklandığını bilmiyorsun. İşte tam bu noktada Windows Performance Counters (Performans Sayaçları) devreye giriyor. Bu yazıda, Windows Server üzerinde performans sorunlarını tespit etmek için performans sayaçlarını nasıl kullanacağını, hangi metriklere bakman gerektiğini ve gerçek dünya senaryolarında bu verileri nasıl yorumlayacağını detaylıca anlatacağım.

Performans Sayaçları Nedir?

Windows, işletim sistemi seviyesinde onlarca farklı bileşeni sürekli olarak izler ve bu verileri “Performance Counter” adı verilen yapılar aracılığıyla dışarıya sunar. CPU kullanımından disk I/O’suna, ağ trafiğinden bellek tüketimine kadar neredeyse her şey sayaçlar aracılığıyla izlenebilir.

Bu sayaçlara erişmenin birkaç yolu var. Grafik arayüz sevenler için Performance Monitor (perfmon.exe) var, komut satırı tutkunları için typeperf ve Get-Counter PowerShell cmdlet’i var. Büyük ölçekli izleme için ise bu verileri merkezi sistemlere aktarabilirsin.

Sayaçlar genellikle şu hiyerarşik yapıda organize edilir:

  • Object (Nesne): İzlenen bileşen kategorisi (örneğin: Processor, Memory, LogicalDisk)
  • Counter (Sayaç): O nesneye ait spesifik metrik (örneğin: % Processor Time)
  • Instance (Örnek): Birden fazla örnek varsa hangisi (örneğin: hangi CPU çekirdeği, hangi disk)

Temel Performans Sayaçları

Hangi sayaçlara bakman gerektiğini bilmek, işin yarısı. Aşağıda kategorilere göre en kritik sayaçları bulacaksın.

CPU Sayaçları

Processor(_Total)% Processor Time: Toplam CPU kullanımı. Sürekli %85’in üzerindeyse sorun var demektir.

Processor(_Total)% Privileged Time: Kernel mode CPU kullanımı. Bu değer %25’i aşıyorsa driver veya sistem servislerinde bir sorun olabilir.

Processor(_Total)% User Time: Kullanıcı modunda çalışan uygulamaların CPU tüketimi.

SystemProcessor Queue Length: CPU kuyruğu uzunluğu. Bu değerin CPU çekirdeği başına 2’nin üzerinde olması ciddi bir CPU darboğazı işaretidir. 8 çekirdekli bir sunucuda 16’nın üzeri alarm vermelidir.

SystemContext Switches/sec: Bağlam değiştirme hızı. Aşırı yüksek değerler (saniyede 15.000 üzeri) thread çekişmesine işaret edebilir.

Bellek Sayaçları

MemoryAvailable MBytes: Kullanılabilir bellek miktarı. Bu değerin toplam RAM’in %10’unun altına düşmesi kritik bir uyarıdır.

MemoryPages/sec: Disk’e sayfalama hızı. Sürekli 1000’in üzerindeyse bellek yetersiz.

MemoryPage Faults/sec: Sayfa hataları. Hard page fault’lar disk erişimi gerektirdiği için performansı ciddi şekilde etkiler.

MemoryPool Nonpaged Bytes: Sayfalama dışı bellek havuzu. Sürekli artıyorsa muhtemelen bir bellek sızıntısı var.

Disk Sayaçları

LogicalDisk(*)% Disk Time: Diskin meşgul olduğu süre yüzdesi. %90’ın üzeri sorunlu.

LogicalDisk(*)Avg. Disk Queue Length: Disk kuyruğu uzunluğu. Disk başına 2’nin üzeri darboğaz göstergesi.

LogicalDisk(*)Avg. Disk sec/Read ve Avg. Disk sec/Write: Disk okuma/yazma gecikmeleri. SSD için 1-2ms normal, HDD için 10-20ms normal kabul edilir. 50ms üzeri ciddi sorun.

LogicalDisk(*)Disk Transfers/sec: IOPS değeri. Storage sisteminizin IOPS kapasitesiyle karşılaştırmalı değerlendirilmeli.

Ağ Sayaçları

Network Interface(*)Bytes Total/sec: Toplam ağ trafiği. Kart kapasitesinin %80’ini geçiyorsa dikkat et.

Network Interface(*)Packets Received Errors: Alınan paket hataları. Sıfır olmalı, değilse kablo/NIC sorunu var.

Network Interface(*)Output Queue Length: Ağ çıkış kuyruğu. 2’nin üzeri darboğaz.

Komut Satırından Performans Verisi Toplama

Grafik arayüz her zaman pratik değil. Özellikle Core kurulumlarında veya uzaktan erişimde komut satırı araçları hayat kurtarır.

typeperf Kullanımı

# Anlık CPU kullanımını göster
typeperf "Processor(_Total)% Processor Time"

# Belirli sayaçları 5 saniye aralıkla 60 kez örnekle ve CSV'ye kaydet
typeperf "Processor(_Total)% Processor Time" "MemoryAvailable MBytes" "LogicalDisk(_Total)% Disk Time" -si 5 -sc 60 -o C:PerfLogsperformans.csv

# Uzak sunucudan veri topla
typeperf "\SUNUCU01Processor(_Total)% Processor Time" -si 10 -sc 120

# Sayaç listesini dosyadan oku
typeperf -cf C:PerfLogssayaclar.txt -si 5 -sc 300 -o C:PerfLogssonuclar.csv

PowerShell ile Performans Verisi

PowerShell, performans izleme konusunda çok daha güçlü seçenekler sunuyor.

# Anlık performans verisi al
Get-Counter "Processor(_Total)% Processor Time"

# Birden fazla sayacı aynı anda izle
Get-Counter -Counter "Processor(_Total)% Processor Time", "MemoryAvailable MBytes", "LogicalDisk(_Total)% Disk Time" -SampleInterval 5 -MaxSamples 20

# Tüm Processor örneklerini listele
Get-Counter -ListSet "Processor" | Select-Object -ExpandProperty Counter

# Sürekli izleme ve log tutma
$sayaclar = @(
    "Processor(_Total)% Processor Time",
    "MemoryAvailable MBytes",
    "MemoryPages/sec",
    "LogicalDisk(_Total)Avg. Disk Queue Length",
    "Network Interface(*)Bytes Total/sec"
)

Get-Counter -Counter $sayaclar -SampleInterval 10 -MaxSamples 360 |
    Export-Counter -Path "C:PerfLogsperformans_$(Get-Date -Format 'yyyyMMdd_HHmm').blg" -FileFormat BLG

Data Collector Set (DCS) ile Otomatik Veri Toplama

Uzun vadeli analiz için Data Collector Set kullanmak en iyi yöntem. Hem GUI hem de komut satırından yönetilebilir.

# Komut satırından DCS oluştur
logman create counter PerfAnaliz `
    -c "Processor(_Total)% Processor Time" `
    "MemoryAvailable MBytes" `
    "MemoryPages/sec" `
    "LogicalDisk(*)Avg. Disk Queue Length" `
    "LogicalDisk(*)Avg. Disk sec/Read" `
    "LogicalDisk(*)Avg. Disk sec/Write" `
    "Network Interface(*)Bytes Total/sec" `
    -si 00:00:05 `
    -f bincirc `
    -max 500 `
    -o "C:PerfLogsPerfAnaliz"

# DCS'yi başlat
logman start PerfAnaliz

# DCS'yi durdur
logman stop PerfAnaliz

# DCS durumunu kontrol et
logman query PerfAnaliz

BLG Dosyalarını Analiz Etme

Topladığın BLG dosyalarını PowerShell ile analiz edebilirsin.

# BLG dosyasını okuyup CSV'ye dönüştür
$veri = Import-Counter -Path "C:PerfLogsPerfAnaliz.blg"
$veri | Export-Counter -Path "C:PerfLogsanaliz.csv" -FileFormat CSV

# BLG'den istatistiksel özet al
Import-Counter -Path "C:PerfLogsPerfAnaliz.blg" -Summary

# Belirli sayaca ait verileri filtrele ve maksimum değeri bul
$cpuVeri = Import-Counter -Path "C:PerfLogsPerfAnaliz.blg" |
    Select-Object -ExpandProperty CounterSamples |
    Where-Object {$_.Path -like "*Processor Time*"}

$cpuVeri | Measure-Object -Property CookedValue -Maximum -Minimum -Average

Gerçek Dünya Senaryosu 1: SQL Server Sunucusu Yavaşlıyor

Bir müşterimde SQL Server çalıştıran sunucu her sabah 09:00-11:00 arasında ciddi performans sorunları yaşıyordu. Kullanıcılar raporların çok yavaş geldiğinden şikayet ediyordu. İşte adım adım nasıl analiz ettiğimi anlatayım.

İlk adım olarak sorunlu saatlerde veri toplamaya başladım:

# Sorun yaşanan saat aralığında kapsamlı veri topla
$sqlSayaclar = @(
    "Processor(_Total)% Processor Time",
    "Processor(_Total)% Privileged Time",
    "SystemProcessor Queue Length",
    "MemoryAvailable MBytes",
    "MemoryPages/sec",
    "MemoryPool Nonpaged Bytes",
    "LogicalDisk(D:)Avg. Disk sec/Read",
    "LogicalDisk(D:)Avg. Disk sec/Write",
    "LogicalDisk(D:)Avg. Disk Queue Length",
    "LogicalDisk(L:)Avg. Disk sec/Write",
    "SQLServer:Buffer ManagerBuffer cache hit ratio",
    "SQLServer:Buffer ManagerPage life expectancy",
    "SQLServer:SQL StatisticsBatch Requests/sec",
    "SQLServer:Wait Statistics(*)Lock waits"
)

logman create counter SQLAnaliz `
    -c $sqlSayaclar `
    -si 00:00:10 `
    -f bincirc `
    -max 1000 `
    -o "C:PerfLogsSQLAnaliz" `
    -b 09:00:00 `
    -e 11:30:00

Analiz sonucunda şu tespitleri yaptık:

  • Page Life Expectancy değeri 300’ün altına düşüyordu (sağlıklı değer için 300+ saniye beklenir)
  • Buffer Cache Hit Ratio %95’in altındaydı
  • Disk Queue Length D: sürücüsünde zirveye çıkıyordu
  • Available MBytes sabah iş yoğunluğunda dramatik düşüş gösteriyordu

Sorunun kaynağı: Sabah çalışan birkaç büyük rapor sorgusu, SQL Server buffer pool’unu boşaltıyor ve sürekli diskten okuma yapmak zorunda kalıyordu. Çözüm olarak SQL Server’a daha fazla bellek tahsis ettik ve sorgu planlarını optimize ettik.

Gerçek Dünya Senaryosu 2: IIS Sunucusunda Aralıklı Yavaşlama

Bir e-ticaret sitesinde yoğun saatlerde sayfa yüklenme sürelerinin arttığına dair şikayetler geliyordu. Sorun aralıklı olduğu için tespit etmek zorlaşıyordu.

Bu tür aralıklı sorunlar için sürekli veri toplamanın yanı sıra alert mekanizması kurmak gerekiyor:

# Threshold aşıldığında uyarı veren PowerShell scripti
$esik = 85
$kontrol_suresi = 300  # 5 dakika
$log_dosyasi = "C:PerfLogscpu_alert_$(Get-Date -Format 'yyyyMMdd').log"

while ($true) {
    $cpu = (Get-Counter "Processor(_Total)% Processor Time").CounterSamples.CookedValue
    $bellek = (Get-Counter "MemoryAvailable MBytes").CounterSamples.CookedValue
    $disk_kuyruk = (Get-Counter "LogicalDisk(_Total)Avg. Disk Queue Length").CounterSamples.CookedValue

    $zaman = Get-Date -Format "yyyy-MM-dd HH:mm:ss"

    if ($cpu -gt $esik) {
        $mesaj = "$zaman - UYARI: CPU kullanimi %$([math]::Round($cpu,1)) esigi asti!"
        Write-Host $mesaj -ForegroundColor Red
        Add-Content -Path $log_dosyasi -Value $mesaj

        # Yuksek CPU anında aktif processleri kaydet
        $processes = Get-Process | Sort-Object CPU -Descending | Select-Object -First 10
        $processes | ForEach-Object {
            Add-Content -Path $log_dosyasi -Value "  $($_.Name) - CPU: $($_.CPU) - RAM: $([math]::Round($_.WorkingSet/1MB,1))MB"
        }
    }

    Start-Sleep -Seconds $kontrol_suresi
}

Bu script sayesinde yüksek CPU anındaki process listesini yakalayabildik. Sorunun kaynağı: Belirli saatlerde çalışan bir thumbnail oluşturma işlemi hem CPU hem disk kaynaklarını tüketiyordu. Bu işlem gece saatlerine alınarak sorun çözüldü.

Performance Monitor ile Görsel Analiz

Komut satırı güçlü ama bazen görsel analiz daha hızlı sonuç veriyor. perfmon.exe’yi açtığında seni karşılayan arayüzde birkaç kritik özellik var.

Performance Monitor görünümü anlık izleme için kullanılır. Sayaç eklerken dikkat etmen gereken bazı noktalar:

  • Aynı grafik üzerinde farklı ölçek birimlerine sahip sayaçları karşılaştırırken “Scale” ayarını düzenle
  • Renk kodlaması yaparak CPU, bellek ve disk sayaçlarını birbirinden ayırt et
  • Baseline almak için normal çalışma saatlerinde de veri topla ve bunu karşılaştırma referansı olarak kullan

Data Collector Sets bölümünde hazır şablonlar var. “System Performance” şablonu başlangıç için gayet iyi bir seçenek. Bu şablon 60 saniyelik veri toplama yapıyor ve sonunda otomatik rapor üretiyor.

Performans Baseline Oluşturma

Bir anomaliyi tespit edebilmek için önce normalin ne olduğunu bilmen gerekiyor. Baseline (referans değer) oluşturmak bu yüzden kritik önem taşıyor.

# Haftalik baseline verisi toplama - her gun farkli bir dosyaya kaydet
$bugun = Get-Date -Format "dddd"
$log_yolu = "C:PerfLogsBaseline$bugun"

if (-not (Test-Path $log_yolu)) {
    New-Item -ItemType Directory -Path $log_yolu
}

$baseline_sayaclar = @(
    "Processor(_Total)% Processor Time",
    "Processor(_Total)% Privileged Time",
    "SystemProcessor Queue Length",
    "SystemContext Switches/sec",
    "MemoryAvailable MBytes",
    "MemoryPages/sec",
    "MemoryPool Nonpaged Bytes",
    "LogicalDisk(*)% Disk Time",
    "LogicalDisk(*)Avg. Disk Queue Length",
    "LogicalDisk(*)Avg. Disk sec/Read",
    "LogicalDisk(*)Avg. Disk sec/Write",
    "Network Interface(*)Bytes Total/sec",
    "Network Interface(*)Packets Received Errors"
)

# 8 saat boyunca 30 saniyede bir ornek al
Get-Counter -Counter $baseline_sayaclar -SampleInterval 30 -MaxSamples 960 |
    Export-Counter -Path "$log_yolubaseline_$(Get-Date -Format 'HHmm').blg" -FileFormat BLG

Write-Host "Baseline verisi toplandi: $log_yolu" -ForegroundColor Green

Baseline oluştururken şunlara dikkat et:

  • En az iki haftalık veri topla ki hafta içi/hafta sonu farklarını göresin
  • Hem yoğun hem de sakin saatlerde veri topla
  • Bakım pencereleri sırasında toplanan verileri baseline’a dahil etme
  • Yeni uygulama veya güncelleme sonrasında baseline’ı yenile

Resource Monitor ile Detaylı Analiz

perfmon.exe bazen yüksek seviyeli kalabilir. Daha derin analiz için Resource Monitor (resmon.exe) mükemmel bir araç. Komut satırından şöyle açabilirsin:

# Resource Monitor'u aç
resmon.exe

# Veya Run dialog'dan
# resmon

Resource Monitor’ün güçlü yönleri:

  • Hangi process’in hangi dosyaya eriştiğini görebilirsin
  • Ağ bağlantılarını process bazında izleyebilirsin
  • Disk I/O’sunu gerçek zamanlı olarak takip edebilirsin
  • Bekleyen disk işlemlerini görebilirsin

WMI ile Performans Verisi Sorgulama

Uzak sistemleri merkezi olarak izlemek için WMI sorguları çok işe yarıyor.

# Uzak sunucudan CPU bilgisi al
$sunucu = "UZAKSUNACU01"
$kimlik = Get-Credential

$cpu = Get-WmiObject -Class Win32_PerfFormattedData_PerfOS_Processor `
    -ComputerName $sunucu `
    -Credential $kimlik `
    -Filter "Name='_Total'" |
    Select-Object PercentProcessorTime, PercentPrivilegedTime, PercentUserTime

Write-Host "CPU Kullanimi: $($cpu.PercentProcessorTime)%"

# Birden fazla sunucudan ayni anda veri topla
$sunucular = @("SUNUCU01", "SUNUCU02", "SUNUCU03", "SUNUCU04")

$sonuclar = $sunucular | ForEach-Object -Parallel {
    $s = $_
    $cpu = Get-WmiObject -Class Win32_PerfFormattedData_PerfOS_Processor `
        -ComputerName $s `
        -Filter "Name='_Total'" |
        Select-Object -ExpandProperty PercentProcessorTime

    $bellek = Get-WmiObject -Class Win32_OperatingSystem `
        -ComputerName $s |
        Select-Object FreePhysicalMemory, TotalVisibleMemorySize

    [PSCustomObject]@{
        Sunucu = $s
        CPUYuzdesi = $cpu
        BelekMB = [math]::Round($bellek.FreePhysicalMemory / 1024, 0)
        ToplamBelekMB = [math]::Round($bellek.TotalVisibleMemorySize / 1024, 0)
    }
} -ThrottleLimit 5

$sonuclar | Format-Table -AutoSize

Yaygın Performans Sorunları ve Teşhis Yöntemleri

Yüksek CPU Ama Düşük Disk Aktivitesi

Bu senaryo genellikle CPU-bound bir uygulama veya sonsuz döngü yapan bir process işaret eder.

  • SystemProcessor Queue Length yüksekse CPU darboğazı kesin
  • % Privileged Time yüksekse driver veya antivirus sorunu olabilir
  • Task Manager’da process bazında CPU kullanımına bak
  • Process Explorer ile thread düzeyine inin

Yüksek Disk Aktivitesi Ama Düşük CPU

Genellikle bellek yetersizliğinden kaynaklanan sayfalama sorunudur.

  • MemoryPages/sec çok yüksekse RAM eklemek gerekiyor
  • LogicalDiskAvg. Disk Queue Length yüksekse storage altyapısını gözden geçir
  • Paging file boyutu ve konumunu kontrol et

Aralıklı Performans Sorunları

En zor teşhis edileni bunlar. Sürekli veri toplama ve detaylı loglama şart.

  • Task Scheduler’daki zamanlanmış görevleri kontrol et
  • Antivirus scan zamanlamalarını incele
  • SQL Server Agent job’larını gözden geçir
  • Event Viewer’da sorunlu anlardaki hataları incele

Sonuç

Windows Server performans analizi, doğru araçları ve doğru sayaçları bilmekle başlıyor. typeperf ve PowerShell’in Get-Counter cmdlet’i ile anlık ve uzun vadeli veri toplayabilirsin. Data Collector Set’ler ile sistematik baseline oluşturabilir, bu baseline’dan sapmaları tespit ederek sorunları proaktif olarak yakalayabilirsin.

Pratikte en çok işe yarayan yaklaşım şu: Normal çalışma koşullarında iyi bir baseline oluştur, kritik sayaçlar için alert mekanizmaları kur ve sorun yaşandığında eliminde zaten hazır veri olsun. Yangın çıktıktan sonra veri toplamaya çalışmak hem stresli hem de genellikle yetersiz kalıyor.

Hangi sayaçlara odaklanman gerektiği ortamdan ortama değişiyor. SQL Server ağırlıklı bir ortamda buffer manager sayaçları kritikken, IIS tabanlı bir sunucuda ASP.NET ve network sayaçları daha önemli hale geliyor. Zamanla kendi ortamınıza özel bir “izleme paketi” oluşturmak, uzun vadede en verimli yaklaşım oluyor.

Son olarak şunu söyleyeyim: Performans analizi tek seferlik bir iş değil. Düzenli aralıklarla kapasitesi planlama yapmak, büyüme trendlerini takip etmek ve gelecekteki darboğazları önceden tespit etmek, iyi bir sysadmin’in temel görevleri arasında yer alıyor.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir