Yüksek CPU Kullanımı: Windows’ta Kaynak Tespiti
Sunucuya bağlandığında CPU kullanımının %95’in üzerinde olduğunu görmen ve bunun ne zaman başladığını bilmemen, bir sistem yöneticisi için en sinir bozucu durumlardan biridir. Ekip baskı altında, kullanıcılar şikayet ediyor ve sen nereye bakacağını bulmaya çalışıyorsun. Windows Server ortamlarında yüksek CPU tespiti, doğru araçları ve yaklaşımı bildiğinde aslında oldukça sistematik bir süreçtir. Bu yazıda gerçek dünya senaryoları üzerinden adım adım ilerleyeceğiz.
İlk Adım: Durumu Anlamak
Paniklemeden önce birkaç temel soruyu yanıtlaman gerekiyor. CPU kullanımı anlık mı yoksa sürekli mi yüksek? Belirli bir saatte mi başlıyor yoksa rastgele mi? Bu sorular, araştırma yöntemini belirleyecek.
Task Manager ile hızlı genel bakış için masaüstünde sağ tık yerine doğrudan Ctrl+Shift+Esc kullanmayı alışkanlık haline getir. Ancak Task Manager sana yüzeysel bilgi verir. Hangi sürecin CPU yediğini görürsün ama neden yediğini göremezsin.
Gerçek dünya senaryosu: Bir müşteri sunucusunda svchost.exe işleminin CPU’yu %80 seviyesinde tuttuğunu gördük. Task Manager’da “svchost.exe” yazıyor ama bu işlem onlarca farklı Windows servisini barındırabiliyor. Buradan sonra işin içine girmek gerekiyor.
Görev Yöneticisi’nin Ötesine Geçmek: Process Explorer
Microsoft Sysinternals’ın Process Explorer aracı, bir sistem yöneticisinin elinden düşürmemesi gereken araçların başında gelir. Ücretsizdir, kurulum gerektirmez ve Task Manager’ın göremediği her şeyi gösterir.
Process Explorer ile yapabileceklerin:
- svchost.exe gibi host işlemlerin içinde hangi servislerin çalıştığını görme
- İşlemlerin CPU geçmişini grafiksel olarak takip etme
- Bir işlemin hangi DLL dosyalarını yüklediğini görme
- Şüpheli işlemleri VirusTotal üzerinden anında tarama
Senaryoya dönelim: svchost.exe üzerine çift tıkladığımızda içinde Windows Update servisinin çalıştığını ve saatlerdir güncelleme indirdiğini gördük. Bazen en karmaşık görünen sorunların en basit nedeni olabilir.
PowerShell ile CPU Kullanımını Tespit Etmek
GUI araçlar yetersiz kaldığında veya remote bir sunucuya bağlandığında PowerShell senin en iyi dostun. Aşağıdaki komutlar gerçek ortamlarda aktif olarak kullandığım komutlardır.
En çok CPU kullanan 10 işlemi listelemek:
Get-Process | Sort-Object CPU -Descending | Select-Object -First 10 Name, CPU, Id, WorkingSet | Format-Table -AutoSize
Bu komut anlık bir fotoğraf verir. Ama CPU kullanımı dalgalıysa, birkaç saniye aralıklarla örnekleme yapmak daha sağlıklı sonuç verir.
Belirli aralıklarla CPU örneklemesi:
$interval = 5
$count = 12
for ($i = 0; $i -lt $count; $i++) {
$timestamp = Get-Date -Format "HH:mm:ss"
$topProcess = Get-Process | Sort-Object CPU -Descending | Select-Object -First 1
Write-Host "$timestamp - En yuksek CPU: $($topProcess.Name) PID:$($topProcess.Id) CPU:$($topProcess.CPU)"
Start-Sleep -Seconds $interval
}
Bu script 1 dakika boyunca her 5 saniyede bir en yüksek CPU kullanan işlemi loglar. Bir dosyaya yönlendirip gece yarısı için schedule edebilirsin.
WMI ile daha detaylı bilgi almak:
Get-WmiObject Win32_Process | Sort-Object -Property @{Expression={$_.KernelModeTime + $_.UserModeTime}; Descending=$true} | Select-Object -First 10 Name, ProcessId, @{Name="CPU_Time"; Expression={($_.KernelModeTime + $_.UserModeTime)/10000000}} | Format-Table -AutoSize
WMI sorgusu kernel mode ve user mode CPU zamanını ayrı ayrı toplar. Bu ayrım önemlidir: eğer kernel mode süresi baskınsa, büyük ihtimalle bir sürücü (driver) problemiyle karşı karşıyasındır.
Performans Monitörü ile Derinlemesine Analiz
Windows’un yerleşik Performance Monitor (perfmon.exe) aracı, uzun süreli sorunları tespit etmek için idealdir. Data Collector Set oluşturarak saatler veya günler boyunca veri toplayabilirsin.
Komut satırından hızlı veri toplamak için:
# 60 saniye boyunca her 2 saniyede bir CPU verisi topla
typeperf "Processor(_Total)% Processor Time" -si 2 -sc 30 -o "C:Logscpu_log.csv"
Bu komut CSV formatında log oluşturur, Excel’de analiz edebilirsin. Şüpheli saatler için bu veriyi Scheduled Task ile otomatikleştirmek altın değerindedir.
Belirli bir işlemin CPU kullanımını izlemek:
# Önce işlemin tam adını bul
$processName = "sqlservr"
typeperf "Process($processName)% Processor Time" -si 5 -sc 60
Gerçek dünya senaryosu: Bir e-ticaret sitesinin SQL Server’ında her gece 02:00-03:00 arası CPU spike’ı yaşanıyordu. Typeperf ile 3 gece boyunca veri topladık ve sorunun her gece çalışan bir backup job’ının tetiklediği istatistik güncelleme işlemiyle çakıştığını bulduk.
Olay Günlükleri: CPU Sorunlarının Sessiz Tanıkları
Event Viewer çoğu zaman göz ardı edilir ama CPU sorunlarının arka planında ne olduğunu anlamak için kritiktir. Özellikle şu log lokasyonlarına bakmalısın:
- Windows Logs > System: Sürücü hataları, servis çökmeleri
- Windows Logs > Application: Uygulama hataları ve uyarıları
- Applications and Services Logs > Microsoft > Windows > TaskScheduler: Scheduled task hataları
PowerShell ile son 1 saatteki kritik sistem olaylarını çekmek:
$startTime = (Get-Date).AddHours(-1)
Get-WinEvent -FilterHashtable @{
LogName = 'System'
Level = 1,2,3
StartTime = $startTime
} | Select-Object TimeCreated, Id, LevelDisplayName, Message | Format-List
Bu komut son 1 saatteki hata ve uyarı seviyesindeki olayları getirir. CPU spike’larıyla zaman damgalarını karşılaştırdığında genellikle anlamlı bir ilişki görürsün.
Windows Defender ve Antivirus: Sık Karşılaşılan Suçlu
Üretim ortamlarında yüksek CPU sorunlarının önemli bir kısmının arkasında antivirus taramaları yatar. Özellikle Windows Defender’ın MsMpEng.exe işlemi, kötü yapılandırılmış sistemlerde CPU’yu felç edebilir.
Defender’ın gerçek zamanlı tarama aktivitesini kontrol etmek:
# Windows Defender durumunu kontrol et
Get-MpComputerStatus | Select-Object AntivirusEnabled, RealTimeProtectionEnabled, LastFullScanTime, LastQuickScanTime
# Defender tarama geçmişine bak
Get-MpThreatDetection | Select-Object -Last 20 ActionSuccess, DetectionSourceTypeID, ProcessName, Resources
Kritik not: Production SQL Server veya Exchange sunucularında Defender’ın tarama dışı klasör listesini doğru yapılandırmak zorunludur. Microsoft’un bu konuda resmi exclude listesi belgesi mevcut.
Scheduled Tasks: Gizli Kaynak Tüketicileri
Birçok sysadmin, CPU sorunlarını incelerken Scheduled Tasks’ları atlar. Oysa zamanlanmış görevler, özellikle bakım pencerelerinde yoğun CPU aktivitesine neden olabilir.
Tüm aktif scheduled task’ları listele:
Get-ScheduledTask | Where-Object {$_.State -eq "Running"} | Select-Object TaskName, TaskPath, State | Format-Table -AutoSize
Son 24 saatte çalışan task’ların geçmişini görmek:
Get-WinEvent -LogName "Microsoft-Windows-TaskScheduler/Operational" | Where-Object {$_.TimeCreated -gt (Get-Date).AddHours(-24) -and $_.Id -eq 200} | Select-Object TimeCreated, @{Name="TaskName"; Expression={$_.Properties[0].Value}} | Sort-Object TimeCreated | Format-Table
Event ID 200, bir görevin tamamlandığını belirtir. Bu kayıtlara bakarak hangi görevin ne zaman çalıştığını ve CPU spike’ıyla örtüşüp örtüşmediğini anlayabilirsin.
WPA ve ETW ile İleri Seviye Analiz
Sorun hala çözülmediyse ve derinde bir şeyler olduğunu hissediyorsan, Windows Performance Analyzer (WPA) ve Event Tracing for Windows (ETW) devreye giriyor. Bu araçlar, kernel seviyesinde ne olduğunu görmeni sağlar.
Windows Performance Recorder ile veri toplamak:
# WPR ile 60 saniyelik CPU profili al
wpr -start CPU -start DiskIO
Start-Sleep -Seconds 60
wpr -stop "C:Logscpu_trace.etl" "CPU yuksek kullanim analizi"
Oluşan .etl dosyasını WPA ile açtığında CPU kullanımını process, thread ve hatta fonksiyon bazında görebilirsin. Bir uygulama geliştiricisiyle birlikte çalışıyorsan bu veriyi paylaşmak, sorunun tam kaynağını bulmalarına yardımcı olur.
Pratik Senaryo: IIS ve Yüksek CPU
Bir web sunucusunda IIS worker process’inin (w3wp.exe) CPU’yu %100’e çektiği durumlar sıkça yaşanır. Bu noktada hangi application pool’un sorun çıkardığını bulmak gerekir.
# Çalışan tüm w3wp.exe işlemlerini application pool adıyla göster
Get-Process -Name "w3wp" | ForEach-Object {
$pid = $_.Id
$appPool = (Get-WmiObject -Namespace "rootWebAdministration" -Class WorkerProcess | Where-Object {$_.ProcessId -eq $pid}).AppPoolName
[PSCustomObject]@{
PID = $pid
CPU = $_.CPU
AppPool = $appPool
WorkingSetMB = [math]::Round($_.WorkingSet64/1MB, 2)
}
} | Sort-Object CPU -Descending
Application pool’u tespit ettikten sonra IIS Failed Request Tracing aktif edilerek hangi request’lerin uzun sürdüğü bulunabilir. Bu özellik, IIS Manager üzerinden ilgili site için açılır.
Gerçek dünya: Bir müşterinin web sunucusunda w3wp.exe her öğleden sonra CPU’yu zirveye taşıyordu. Sorun, application pool’da biriken session nesneleri ve kötü yazılmış bir raporlama modülünün çift döngüye girmesiydi. Request tracing ile 45 saniyelik response süreleri görünce geliştirici ekibine somut kanıt sunabilmiştik.
Dump Analizi: En Derin Seviye
Hangi kod satırının CPU’yu tükettiğini bulmak istiyorsan, process dump almak gerekir. Bu özellikle “sıkışmış” thread’lerin olduğu durumlarda hayat kurtarır.
# Sysinternals ProcDump ile yüksek CPU anında dump al
# CPU kullanımı %80'in üzerinde 10 saniye kalırsa dump al
procdump -c 80 -s 10 -ma w3wp.exe "C:Dumps"
ProcDump, belirtilen koşul sağlandığında otomatik dump alır. Oluşan .dmp dosyasını WinDbg ile açarak thread stack’lerine bakabilirsin. Bu analizi genellikle uygulama sahipleri veya yazılım geliştiricilerle birlikte yaparsın.
CPU Yükünü Azaltmak için Kısa Vadeli Müdahaleler
Sorunun kaynağını tespit ettin ama hemen düzeltemiyorsun. Bu durumda sunucuyu ayakta tutmak için geçici önlemler alabilirsin.
Bir işlemin CPU önceliğini düşürmek:
# Belirli bir işlemin önceliğini düşür (Below Normal)
$process = Get-Process -Name "problematic_process"
$process.PriorityClass = [System.Diagnostics.ProcessPriorityClass]::BelowNormal
Write-Host "Oncelik dusuruldu: $($process.Name)"
CPU afinite ayarını değiştirmek (işlemi belirli CPU çekirdeklerine kısıtlamak):
# İşlemi yalnızca ilk iki CPU çekirdeğine kısıtla
$process = Get-Process -Id 1234
$process.ProcessorAffinity = 3 # Binary: 0011 = Core 0 ve Core 1
Write-Host "Affinity guncellendi"
Bu yöntemler kalıcı çözüm değildir ama krizi atlatmak için zaman kazandırır.
Önemli Kontrol Listesi
CPU sorun tespitinde her seferinde aynı sırayı takip etmek, gözden kaçırma ihtimalini azaltır.
Tespit aşaması:
- Task Manager ile hangi process öne çıkıyor?
- Process Explorer ile o process’in içinde ne çalışıyor?
- PowerShell ile CPU kullanımı zaman bazlı log alındı mı?
- Event Viewer’da aynı zaman diliminde hata var mı?
Bağlam analizi:
- Sorun ne zaman başladı, bu tarihte sistem değişikliği var mıydı?
- Scheduled task’lar incelendi mi?
- Windows Update veya antivirus taraması çakışıyor mu?
- IIS veya SQL varsa o servise özgü loglar bakıldı mı?
Çözüm ve önlem:
- Kısa vadeli stabilizasyon yapıldı mı?
- Kalıcı çözüm için geliştirici veya uygulama sahibine bilgi verildi mi?
- Uyarı sistemi kuruldu mu?
Proaktif İzleme: Sorun Çıkmadan Önce Fark Etmek
Reaktif olmak yerine proaktif olmak, uzun vadede çok daha az stres demektir. Basit bir PowerShell scripti ile CPU eşiği aşıldığında e-posta alabilirsin.
# CPU izleme ve uyarı scripti
$threshold = 85
$checkInterval = 30 # saniye
$smtpServer = "mail.sirket.com"
$alertEmail = "[email protected]"
while ($true) {
$cpuUsage = (Get-WmiObject Win32_Processor | Measure-Object -Property LoadPercentage -Average).Average
if ($cpuUsage -gt $threshold) {
$topProcesses = Get-Process | Sort-Object CPU -Descending | Select-Object -First 5 Name, CPU, Id
$body = "CPU Kullanimi: %$cpuUsage`n`nEn Cok Kullanan Processler:`n"
$topProcesses | ForEach-Object { $body += "$($_.Name) PID:$($_.Id) CPU:$($_.CPU)`n" }
Send-MailMessage -To $alertEmail -From "[email protected]" -Subject "UYARI: Yuksek CPU Kullanimi" -Body $body -SmtpServer $smtpServer
Write-Host "$(Get-Date): Uyari gonderildi - CPU: %$cpuUsage"
}
Start-Sleep -Seconds $checkInterval
}
Bu scripti bir Windows Service veya Scheduled Task olarak çalıştırabilirsin. Daha kurumsal ortamlarda SCOM, Zabbix veya Prometheus gibi izleme araçları bu işi çok daha sağlıklı yapar ama basit bir ortam için bu script işe yarar.
Sonuç
Windows Server’da yüksek CPU sorunlarını çözmek, doğru araçları ve metodolojik yaklaşımı gerektiren bir süreçtir. Task Manager ile başlayıp Process Explorer, PowerShell, Performance Monitor ve gerekirse ETW trace’e kadar ilerleyen bu hiyerarşik yaklaşım, sorunun kaynağını sistematik biçimde daraltır.
En önemli nokta, panik yapmadan ve aceleci kararlar almadan önce yeterli veri toplamaktır. Bir işlemi kill etmeden önce neden yüksek CPU kullandığını anlamak, hem sorunu gerçekten çözmen hem de ileride aynı sorunun tekrarlanmaması için şarttır. Proaktif izleme sistemleri kurmak, sorunu kullanıcılar şikayet etmeden önce fark etmeni sağlar ve bu da sysadmin’in en değerli özelliğidir: öngörülü olmak.
Bu yazıdaki araçların hepsini bir test ortamında denemen, gerçek bir kriz anında çok daha hızlı hareket etmeni sağlayacaktır. İyi sistem yöneticileri araçlarını kriz anında değil, sakin zamanlarda öğrenir.
