Проблеми продуктивності не оголошують про себе ввічливо. Вони проявляються як «додаток відчувається повільно», «RDP лагає», «SQL зависає» або мій улюблений: «вчора було нормально». До того моменту, як ви відкриєте Диспетчер завдань, спайк уже зник із місця злочину.
Get-Counter у PowerShell — це ваша камера спостереження: завжди ввімкнена, з часовими мітками, автоматизована і придатна як доказ. Якщо ви навчитеся читати кілька лічильників так, як SRE читає графіки, ви зможете відокремити голодування CPU від тиску пам’яті або затримок диска за кілька хвилин — не годинами дебагу на відчуттях.
Чому Get‑Counter кращий за клікання по інтерфейсу
PerfMon підходить. Диспетчер завдань підходить. Але «підходить» — це не те, що вам потрібно о 02:13, коли файловий сервер починає таймаути, а у вас є 15 хвилин, поки віце-президент не знайде ваш номер телефону.
Get-Counter перемагає, бо воно:
- Скриптове: повторювані інтервали вибірки, послідовний вихід, простий експорт.
- Дружнє до віддаленого доступу: ту саму команду можна виконати проти кількох хостів.
- Орієнтоване на часові ряди: ви можете зафіксувати спайк, а не лише вчепитися в момент.
- Компоноване: передавайте в пайп, фільтруйте, агрегуйте, розкладати.
До того ж вам не треба «пам’ятати, куди ви клікали» під час інциденту. Команда сама по собі — це запис.
Практичне правило: припиніть запитувати «чи високий CPU?» і почніть питати «який ресурс зараз є обмежувальним реагентом?». CPU, пам’ять і диск — тристоронній поєдинок. Ваше завдання — визначити, хто тримає ніж.
Жарт №1: Якщо ви не базлайните свої лічильники, кожен графік — це «виявлення аномалій», кероване панікою та кавою.
Цікаві факти та історія (що справді допомагає)
- Лічильники продуктивності Windows існували задовго до PowerShell. Вони з’явилися ще за епохи NT; PowerShell пізніше став зручним способом опитувати їх без GUI.
- PerfMon — лише клієнт. Дані лічильників надходять від провайдерів (наприклад,
PerfProc,PerfOS) та інструментування всередині ОС і драйверів. - Інстанси можуть зникати. Лічильники процесів використовують інстанси типу
chrome#3; коли процеси перезапускаються, імена інстансів можуть зміщуватися, ламаючи наївну автоматизацію. - Деякі «класичні» лічильники вводять в оману приховуванням даних. Довжина черги диска може бути оманливою на сучасних стекх із кешуванням і паралелізмом; латентність зазвичай достовірніша.
- Гіпервізори змінили тлумачення «CPU %». Ready time, stolen time та планування хоста можуть спричиняти уповільнення навіть коли CPU в гостьовій ОС виглядає помірним.
- Типи лічильників мають значення. Деякі значення — це швидкості (за секунду), інші — сирі лічильники, ще інші — дроби;
CookedValue— це коли PowerShell робить за вас обчислення. - Інтервал вибірки змінює інтерпретацію. Зразок 1 секунда ловить спайки; 30 секунд їх приховує. Це не філософія — це математика.
- Багато лічильників обчислені, а не виміряні. Наприклад, «% Processor Time» виводиться з дельт простого часу бездіяльності, а не з магічного лічильника CPU.
- Віддалене опитування використовує RPC/Perf інфраструктуру. Воно може блокуватися політикою фаєрвола, посиленням сервісів або правами, навіть якщо WinRM працює.
Практична модель розуміння: CPU vs RAM vs Disk
Вузькі місця CPU: швидкі проблеми, очевидні симптоми, помилкові «виправлення»
Проблеми CPU часто проявляються як високе % Processor Time, довгі черги виконання та загальна в’ялість відповіді. Але з CPU часто стрибають у пастку: бачать 80–90% і відразу просять більше ядер. Іноді це правильно. Часто це пластир над поганим кодом, агресивним антивірусним скануванням, некоректним форматером логів або безкінечним циклом очікування, який мав би спати.
CPU також приховує гріхи віртуалізації. Гість може виглядати «нормально», тоді як хост перевантажений і ваша VM чекає на планування. Якщо ви вимірюєте тільки в гості, ви можете пропустити справжню проблему.
Вузькі місця пам’яті: повільна катастрофа
Тиск пам’яті — це тип проблеми, що повільно псує день, а потім дивом. Windows дуже старається тримати роботу, підтискаючи робочі набори і використовуючи сторінкування. Коли користувачі скаржаться, ви часто вже в «тредмілл сторінкування»: диск починає трясти, CPU починає їстися, і все стає непослідовним. Ось чому діагностика пам’яті має включати як доступну пам’ять, так і активність сторінкування.
Вузькі місця диска: латентність — ключовий показник
Проблеми диска рідко стосуються лише меж пропускної здатності; це питання латентності та хвостової латентності. Система зберігання може видавати вражаючі МБ/с і при цьому зіпсувати додаток, якщо читання займають 50–200 мс під час піків. Для більшості робочих навантажень Windows, якщо ви можете відповісти «яка зараз латентність читання/запису?», ви на півдорозі до виправлення.
І так, «диск» може означати SAN, хмарний том, Storage Spaces, кеш контролера RAID, фільтр-драйвер антивірусу або шторм метаданих файлової системи. Лічильники не назвуть злочинця автоматично, але скажуть, чи слід переслідувати I/O, CPU чи пам’ять першими.
Цитата, яка має бути в кожному on-call рукописі, бо тримає вас чесним:
«Надія — не стратегія.» — генерал Гордон Р. Салліван
Користуйтеся лічильниками. Не надією.
Практичні завдання (команди + вихід + рішення)
Нижче реальні завдання, які ви можете запускати під час інцидентів або для бенчмарку. Кожне містить: команду, що означає вихід, і яке рішення з цього випливає.
Завдання 1: Список доступних лічильників для CPU, пам’яті, диска
cr0x@server:~$ powershell -NoProfile -Command "Get-Counter -ListSet Processor,Memory,PhysicalDisk | Select-Object -ExpandProperty Counter"
\\Processor(*)\\% Processor Time
\\Processor(*)\\% Privileged Time
\\Processor(*)\\% User Time
\\Processor(*)\\Interrupts/sec
\\Processor(*)\\% Idle Time
\\Memory\\Available MBytes
\\Memory\\Committed Bytes
\\Memory\\% Committed Bytes In Use
\\Memory\\Cache Faults/sec
\\Memory\\Pages/sec
\\PhysicalDisk(*)\\Avg. Disk sec/Read
\\PhysicalDisk(*)\\Avg. Disk sec/Write
\\PhysicalDisk(*)\\Disk Reads/sec
\\PhysicalDisk(*)\\Disk Writes/sec
\\PhysicalDisk(*)\\Current Disk Queue Length
Що це означає: Система відкриває ці лічильники; імена можуть відрізнятися залежно від версії ОС і встановлених ролей. Ви не можете опитувати того, чого немає.
Рішення: Обирайте лічильники за питанням, на яке відповідаєте (латентність, пропускна здатність, насичення), а не за тим, що здається знайомим.
Завдання 2: Швидкий знімок CPU (в цілому)
cr0x@server:~$ powershell -NoProfile -Command "Get-Counter '\Processor(_Total)\% Processor Time' | Select-Object -ExpandProperty CounterSamples | Select-Object Path,CookedValue"
Path CookedValue
---- -----------
\\server\\processor(_total)\\% processor time 37.248
Що це означає: CookedValue — це відсоток. Один зразок — підказка, а не вердикт.
Рішення: Якщо високий, не поспішайте. Зробіть короткий часовий ряд наступним.
Завдання 3: Часовий ряд CPU (ловимо спайки)
cr0x@server:~$ powershell -NoProfile -Command "Get-Counter '\Processor(_Total)\% Processor Time' -SampleInterval 1 -MaxSamples 10 | Select-Object -ExpandProperty CounterSamples | Select-Object TimeStamp,CookedValue"
TimeStamp CookedValue
--------- -----------
2/5/2026 2:13:01 AM 41.1
2/5/2026 2:13:02 AM 92.3
2/5/2026 2:13:03 AM 88.7
2/5/2026 2:13:04 AM 54.9
2/5/2026 2:13:05 AM 39.2
2/5/2026 2:13:06 AM 36.8
2/5/2026 2:13:07 AM 35.5
2/5/2026 2:13:08 AM 34.9
2/5/2026 2:13:09 AM 35.2
2/5/2026 2:13:10 AM 36.1
Що це означає: Був реальний спайк (90%+) на кілька секунд. Це може бути нормально (GC, компактинг, заплановані завдання) або патологічно.
Рішення: Якщо спайки корелюють з болем користувачів, з’ясуйте, чи CPU виконує користувацьку роботу чи ядрову роботу далі.
Завдання 4: Час CPU у користувача vs привілейований (тиск ядра)
cr0x@server:~$ powershell -NoProfile -Command "Get-Counter '\Processor(_Total)\% User Time','\Processor(_Total)\% Privileged Time' -SampleInterval 1 -MaxSamples 5 | Select-Object -ExpandProperty CounterSamples | Select-Object Path,CookedValue"
Path CookedValue
---- -----------
\\server\\processor(_total)\\% user time 22.4
\\server\\processor(_total)\\% privileged time 18.7
\\server\\processor(_total)\\% user time 23.1
\\server\\processor(_total)\\% privileged time 41.2
\\server\\processor(_total)\\% user time 21.9
\\server\\processor(_total)\\% privileged time 39.5
Що це означає: Спайки привілейованого часу вказують на роботу в ядрі: драйвери, стек зберігання, фільтр-драйвери антивірусу, важкі мережеві операції, контекстні переключення або шторми переривань.
Рішення: Якщо привілейований час високий, перевірте латентність диска та переривання, перш ніж звинувачувати «додаток».
Завдання 5: Довжина черги процесора (чи очікують потоки?)
cr0x@server:~$ powershell -NoProfile -Command "Get-Counter '\System\Processor Queue Length' -SampleInterval 1 -MaxSamples 10 | Select-Object -ExpandProperty CounterSamples | Select-Object TimeStamp,CookedValue"
TimeStamp CookedValue
--------- -----------
2/5/2026 2:14:01 AM 0
2/5/2026 2:14:02 AM 2
2/5/2026 2:14:03 AM 8
2/5/2026 2:14:04 AM 9
2/5/2026 2:14:05 AM 7
2/5/2026 2:14:06 AM 1
2/5/2026 2:14:07 AM 0
2/5/2026 2:14:08 AM 0
2/5/2026 2:14:09 AM 1
2/5/2026 2:14:10 AM 0
Що це означає: Це Runnable-потоки, що чекають на CPU. На багатоядерній системі інтерпретуйте це відносно кількості ядер. Спайки можуть бути нормою; тривала черга вказує на конкуренцію за CPU.
Рішення: Якщо довжина черги тримається вище кількох на ядро протягом тривалого часу, або зменште навантаження на CPU, або додайте його. Якщо спайк короткий — шукайте джерело спайка.
Завдання 6: Доступна пам’ять (найпростіша перевірка «тісно?»)
cr0x@server:~$ powershell -NoProfile -Command "Get-Counter '\Memory\Available MBytes' -SampleInterval 2 -MaxSamples 5 | Select-Object -ExpandProperty CounterSamples | Select-Object TimeStamp,CookedValue"
TimeStamp CookedValue
--------- -----------
2/5/2026 2:15:01 AM 612
2/5/2026 2:15:03 AM 590
2/5/2026 2:15:05 AM 571
2/5/2026 2:15:07 AM 548
2/5/2026 2:15:09 AM 530
Що це означає: Доступна пам’ять трендиться вниз. Абсолютне «погано» залежить від ролі. Контролери домену та файлові сервери терпіти менше вільної пам’яті, ніж бази даних з високим споживанням пам’яті.
Рішення: Якщо мало пам’яті і вона падає, перевірте Committed Bytes і активність сторінкування перед тим, як заявляти «потрібно більше RAM».
Завдання 7: Тиск коміту (наближаємося до ліміту коміту?)
cr0x@server:~$ powershell -NoProfile -Command "Get-Counter '\Memory\% Committed Bytes In Use','\Memory\Committed Bytes' | Select-Object -ExpandProperty CounterSamples | Select-Object Path,CookedValue"
Path CookedValue
---- -----------
\\server\\memory\\% committed bytes in use 91.6
\\server\\memory\\committed bytes 2.941943e+10
Що це означає: Близько 90% використання коміту — це сигнал тривоги. Коміт — це віртуальна пам’ять, яка має бути підтримана RAM або файлом підкачки. Якщо коміт досягає 100%, виділення пам’яті відмовляються і сервіси падають по-креативному.
Рішення: При постійному 85–95%+ коміту зменшуйте використання пам’яті, виправляйте витоки або збільшуйте RAM/pagefile. Не чекайте на 100%.
Завдання 8: Частота сторінкування (система трясе?)
cr0x@server:~$ powershell -NoProfile -Command "Get-Counter '\Memory\Pages/sec' -SampleInterval 1 -MaxSamples 10 | Select-Object -ExpandProperty CounterSamples | Select-Object TimeStamp,CookedValue"
TimeStamp CookedValue
--------- -----------
2/5/2026 2:16:01 AM 12
2/5/2026 2:16:02 AM 18
2/5/2026 2:16:03 AM 220
2/5/2026 2:16:04 AM 410
2/5/2026 2:16:05 AM 395
2/5/2026 2:16:06 AM 205
2/5/2026 2:16:07 AM 44
2/5/2026 2:16:08 AM 16
2/5/2026 2:16:09 AM 14
2/5/2026 2:16:10 AM 13
Що це означає: Сплеск сторінкування може бути нормальний. Тривале високе сторінкування разом із низькою доступною пам’яттю і зростаючою латентністю диска — класичний тиск пам’яті.
Рішення: Якщо сторінкування тривале і латентність диска зростає, вважайте пам’ять головним вузьким місцем, навіть якщо «диск зайнятий». Диск тут — жертва.
Завдання 9: Латентність диска по томах (ключовий показник)
cr0x@server:~$ powershell -NoProfile -Command "Get-Counter '\PhysicalDisk(*)\Avg. Disk sec/Read','\PhysicalDisk(*)\Avg. Disk sec/Write' | Select-Object -ExpandProperty CounterSamples | Sort-Object CookedValue -Descending | Select-Object -First 8 Path,CookedValue"
Path CookedValue
---- -----------
\\server\\physicaldisk(1 d:)\\avg. disk sec/write 0.187
\\server\\physicaldisk(1 d:)\\avg. disk sec/read 0.142
\\server\\physicaldisk(0 c:)\\avg. disk sec/write 0.021
\\server\\physicaldisk(0 c:)\\avg. disk sec/read 0.009
Що це означає: Латентність у секундах. 0.187 сек — це 187 мс запису, що погано для більшості транзакційних навантажень. Читання 142 мс теж небажані.
Рішення: Якщо певний том показує високу латентність, сфокусуйте розслідування там: яке навантаження його лупає, що змінилося, чи це проблема ємності, шляху чи бекенду.
Завдання 10: Довжина черги диска (контекст, а не вердикт)
cr0x@server:~$ powershell -NoProfile -Command "Get-Counter '\PhysicalDisk(*)\Current Disk Queue Length' | Select-Object -ExpandProperty CounterSamples | Sort-Object CookedValue -Descending | Select-Object -First 6 Path,CookedValue"
Path CookedValue
---- -----------
\\server\\physicaldisk(1 d:)\\current disk queue length 23
\\server\\physicaldisk(0 c:)\\current disk queue length 1
Що це означає: Запити, що чекають на диск. Черга 23 може бути нормальною на глибокій паралельній системі зберігання — або ж жахливою на одному SATA-диску. Без латентності довжина черги — лише частина історії.
Рішення: Використовуйте довжину черги для підкріплення висновків про латентність, а не як заміну їй.
Завдання 11: Пропускна здатність диска (перевантажуємо пропускну здатність?)
cr0x@server:~$ powershell -NoProfile -Command "Get-Counter '\PhysicalDisk(*)\Disk Read Bytes/sec','\PhysicalDisk(*)\Disk Write Bytes/sec' | Select-Object -ExpandProperty CounterSamples | Sort-Object CookedValue -Descending | Select-Object -First 10 Path,CookedValue"
Path CookedValue
---- -----------
\\server\\physicaldisk(1 d:)\\disk write bytes/sec 8.941122e+07
\\server\\physicaldisk(1 d:)\\disk read bytes/sec 2.110294e+07
\\server\\physicaldisk(0 c:)\\disk write bytes/sec 1.240122e+06
\\server\\physicaldisk(0 c:)\\disk read bytes/sec 3.901220e+06
Що це означає: Bytes/sec. На D: ви робите ~89 MB/s записів і ~21 MB/s читань. Це може бути нормально для бекапу, катастрофічно для латентнісно-чутливої БД — або й те й інше.
Рішення: Якщо пропускна здатність висока і латентність теж висока — ви щось насичуєте. Якщо пропускна низька, а латентність висока — у вас конкуренція, проблеми бекенду або патологічний патерн I/O.
Завдання 12: Який процес їсть CPU (топ-винуватці)
cr0x@server:~$ powershell -NoProfile -Command "Get-Process | Sort-Object CPU -Descending | Select-Object -First 8 Name,Id,CPU,WorkingSet64"
Name Id CPU WorkingSet64
---- -- --- ------------
w3wp 4120 812.3 1245184000
MsMpEng 2788 410.7 512245760
sqlservr 1556 209.1 8421191680
svchost 1020 88.5 210796544
Що це означає: Це накопичений час CPU з початку запуску процесу, а не миттєвий CPU%. Все одно корисно: якщо щось має абсурдний CPU time при невеликому аптаймі, це кандидат.
Рішення: Якщо CPU зараз високий, зв’яжіть це з часовими рядами; якщо топ-винуватець — сканер безпеки, перенесіть або налаштуйте виключення (обережно, з керуванням).
Завдання 13: Віддалена перевірка CPU на кількох серверах
cr0x@server:~$ powershell -NoProfile -Command "$servers='app01','app02','db01'; Get-Counter '\Processor(_Total)\% Processor Time' -ComputerName $servers | Select-Object -ExpandProperty CounterSamples | Select-Object PSComputerName,TimeStamp,CookedValue"
PSComputerName TimeStamp CookedValue
-------------- --------- -----------
app01 2/5/2026 2:17:01 AM 18.2
app02 2/5/2026 2:17:01 AM 22.7
db01 2/5/2026 2:17:01 AM 79.4
Що це означає: Ви щойно встановили зону ураження: БД гаряча, додатки — ні. Ось як уникнути випадкової «шарудної» діагностики.
Рішення: Сфокусуйтеся на db01 далі: латентність диска, поведінка кеша буферів, сторінкування та тиск запитів.
Завдання 14: Експортуйте короткий знімок у CSV як доказ
cr0x@server:~$ powershell -NoProfile -Command "$c='\Processor(_Total)\% Processor Time','\Memory\Available MBytes','\Memory\Pages/sec','\PhysicalDisk(_Total)\Avg. Disk sec/Read','\PhysicalDisk(_Total)\Avg. Disk sec/Write'; Get-Counter $c -SampleInterval 2 -MaxSamples 30 | Export-Counter -Path C:\temp\triage.blg"
Що це означає: Ви зафіксували 60-секундне вікно у файл BLG. Це нативний PerfMon формат, який можна відкрити пізніше або розпарсити.
Рішення: Під час інцидентів завжди збирайте докази перед перезапуском. «Ми перезавантажили й це зникло» — не корінна причина.
Завдання 15: Розпарсити BLG і конвертувати в CSV (передати іншим)
cr0x@server:~$ powershell -NoProfile -Command "Import-Counter C:\temp\triage.blg | Export-Counter -FileFormat CSV -Path C:\temp\triage.csv"
Що це означає: Тепер у вас є CSV, який можна відкрити в Excel, імпортувати в time-series сховище або дифити з базовою лінією.
Рішення: Використовуйте CSV, щоб показати тренди (латентність зростає разом із сторінкуванням, CPU спайк із ядровим часом) і уникати дебатів «це здається».
Завдання 16: Надійно моніторити конкретний том (уникати пастки невірного інстансу)
cr0x@server:~$ powershell -NoProfile -Command "Get-Counter -ListSet PhysicalDisk | Select-Object -ExpandProperty PathsWithInstances | Where-Object { $_ -like '*Avg. Disk sec/Read*' } | Select-Object -First 8"
\\PhysicalDisk(0 C:)\\Avg. Disk sec/Read
\\PhysicalDisk(1 D:)\\Avg. Disk sec/Read
\\PhysicalDisk(_Total)\\Avg. Disk sec/Read
\\PhysicalDisk(2 E:)\\Avg. Disk sec/Read
Що це означає: Ви перераховуєте точні шляхи інстансів. Це рятує від вибірки інстансу, якого немає на іншому сервері (або яке змінило ім’я).
Рішення: Завжди знаходьте шляхи інстансів програмно при написанні скриптів для флоту.
Швидкий план діагностики
Це послідовність «в мене є п’ять хвилин». Ви не доводите тезу. Ви знаходите вузьке місце достатньо швидко, щоб зупинити кровотечу.
Перше: визначте охоплення симптомів
- Один хост чи багато? Швидко зніміть CPU на підозрюваних серверах (Завдання 13). Якщо гарячий лише один сервер, не кип’ятіть океан.
- Один том чи багато? Перевірте латентність диска по томах (Завдання 9). Якщо лише D: страждає, не чіпайте C:.
Друге: ідентифікуйте обмежувальний ресурс
- Насичення CPU? Дивіться
\Processor(_Total)\% Processor Timeі\System\Processor Queue Length(Завдання 3 і 5). Високий CPU без черги може все одно бути «нагрузі, але працює». Висока черга означає, що потоки чекають. - Тиск пам’яті? Перевірте
\Memory\Available MBytes,\Memory\% Committed Bytes In Useі\Memory\Pages/sec(Завдання 6–8). Низька доступна + високий коміт + стале сторінкування — це підпис. - Латентність диска? Перевірте
\PhysicalDisk(*)\Avg. Disk sec/ReadіWrite(Завдання 9). Якщо латентність висока, усе над нею виглядатиме погано.
Третє: вирішіть, пом’якшувати чи розслідувати
- Якщо CPU — вузьке місце: знайдіть топ-процеси, перевірте привілейований час (Завдання 4 і 12). Пом’якшення: обмеження, перенесення пакетних робіт, тимчасове масштабування. Не перезапускайте служби без причини, якщо це не витік чи runaway.
- Якщо пам’ять — вузьке місце: зупиніть зростання (витік процесу, неконтрольований кеш, неправильні налаштування). Пом’якшення: зменшити навантаження, перезапустити винуватця за потреби, налаштувати pagefile. Якщо йде інтенсивне сторінкування, диск виглядає підозрілим — ігноруйте цей червоний гачок.
- Якщо латентність диска — вузьке місце: ідентифікуйте том і навантаження. Пом’якшення: призупиніть важкі роботи, перемістіть тимчасові шляхи, перевірте здоров’я бекенду або зробіть failover. Додавати CPU до проблеми з латентністю зберігання — це як кричати на індикатор завантаження.
Три корпоративні міні-історії з практики
Міні-історія №1: Інцидент через хибне припущення
Середнє підприємство мало критичний Windows файловий сервер, який «випадково зависав» щоранку в робочі дні. Перший реcпондер припустив: «CPU спайки о 9 ранку, значить це CPU». Вони попросили більший VM та більше vCPU. Запит ухвалили, бо звучало логічно, і всім подобається чиста історія закупівель.
Після зміни зависання продовжувалися. CPU виглядав нижчим, але досвід користувачів не поліпшився. Це мало бути підказкою: знизивши використання CPU без поліпшення латентності означає, що CPU не був обмежувачем.
Другий респондент зробив нудну, але корисну річ: захопив хвилинний слід лічильників під час події. \PhysicalDisk(…)\Avg. Disk sec/Write виріс із мілісекунд до сотень мілісекунд. Водночас \Memory\Pages/sec був піднятий, а \Processor(_Total)\% Privileged Time — спайки. Підсумок: підсистема зберігання таймаутила під навантаженням записів.
Причина була не в абстрактному «диск повільний». Це було заплановане завдання, яке скидало мільйони дрібних файлів у одну директорію на тому ж томі, де в той час запускалися VSS-знімки. Метаданні + знімки + бекенд-конкуренція: ідеальний шторм нудних поведінок Windows.
Виправлення не вимагало більше CPU. Потрібно було перенести час виконання роботи, розподілити файли по директоріях, змінити час знімків і додати окремий том для цього навантаження. Заощаджені на необґрунтованих CPU кошти пізніше пішли на реальні покращення зберігання.
Міні-історія №2: Оптимізація, що відкотилася назад
Команда додатка захотіла швидших деплоїв. Вони налаштували Windows сервіс кешувати більше даних у пам’яті, щоб зменшити виклики до БД. Це спрацювало в стенді. У проді теж — доки трафік не виріс і кеш не перейшов «м’яку» межу.
Використання пам’яті повільно росло. Ніхто не помічав, бо сервери «мали багато RAM» і Windows не сигналізував голосно. Але \Memory\% Committed Bytes In Use повзло вгору. Потім почалося сторінкування. Латентність диска зросла. Привілейований час CPU теж. Система зайшла в класичний тредмілл сторінкування: технічно все «вгору», але час відповіді жахливий.
Перший спробований фікс — перемістити pagefile на швидший том. Це трохи допомогло, лише маскуючи проблему і продовжуючи інцидент. Це пастка: оптимізація сторінкування — як ставити кращі поручні на сходах у підвал, в якому вам не варто жити.
Правильне вирішення — обмежити кеш, додати політику витіснення і відокремити «гарячі» об’єкти від «необов’язкових». Також ввели простий алерт по лічильниках: якщо коміт високий і сторінкування перевищує поріг кілька хвилин — команда отримує сповіщення раніше за користувачів.
Урок: деякі «оптимізації продуктивності» — це насправді стратегії споживання ресурсів. Якщо ви не вимірюєте коміт і сторінкування, можна випустити тайм-бомбу під прапором фічі.
Міні-історія №3: Нудна, але правильна практика, що врятувала день
Фінансове середовище виконувало нічні пакетні завдання: імпорти, генерацію звітів та ETL на Windows серверах, підключених до спільної підсистеми зберігання. Роботи були прогнозовані, але середовище мало одну річ, якої бракує багатьом: базові лінії. Щотижня заплановане завдання захоплювало короткий слід лічильників під час пікових вікон пакетів і архівувало його.
Однієї ночі звіти почали не встигати. Операційна команда не лаялася, хто що змінив. Вони порівняли тижнево збережені сліди і подивилися латентність і пропускну здатність диска. Латентність стрибнула на одному томі, а пропускна залишалась стабільною. Цей патерн кричав: «конкуренція бекенду або проблема шляху», а не «збільшилося навантаження».
Вони перевірили кілька серверів. Та сама тома, те саме вікно часу, та сама сигнатура латентності. Це встановило, що проблему не створив один «шумний сусід» в одній VM. Це було системне.
Інженери сховища знайшли подію failover шляху на боці SAN, яка не відновилася до оптимальних шляхів, залишивши трафік на субоптимальному маршруті. Виправлення шляху одразу відновило латентність, і пакетні завдання завершилися в нормальні терміни.
Це не було героїзмом. Це була рутинна робота зі збору доказів. Нудна дисципліна — базові сліди — перетворила потенціальну нічну війну на 30-хвилинне виправлення.
Жарт №2: Найнадійніша система моніторингу — та, яку ви налаштуєте до того, як ваш бос дізнається слово «латентність».
Поширені помилки (симптом → коренева причина → виправлення)
1) «CPU лише 40%, але сервер повільний»
Симптом: Користувачі бачать таймаути; CPU виглядає помірним.
Коренева причина: Латентність диска або тиск пам’яті призводять до блокувань потоків на I/O; CPU здається «вільним», бо потоки чекають.
Виправлення: Перевірте \PhysicalDisk(*)\Avg. Disk sec/Read/Write і \Memory\Pages/sec. Якщо латентність висока — виправляйте шлях I/O або навантаження. Якщо сторінкування високе — вирішуйте тиск пам’яті.
2) «Довжина черги диска висока — значить, проблема зі сховищем»
Симптом: Спайки черги; хтось одразу сигналить команді сховища.
Коренева причина: Довжина черги залежить від контексту; вона зростає при нормальному паралельному I/O і кешуванні. Також може зростати під час сторінкування через пам’ять.
Виправлення: Використовуйте латентність як основний індикатор. Довжина черги без високої латентності — не інцидент. Довжина черги з високою латентністю — дієво.
3) «Ми виправили це, додавши vCPU»
Симптом: CPU % знизився після додавання ядер; користувачі все одно скаржаться.
Коренева причина: CPU не був обмежувачем; ви просто змінили знаменник. Або ви внесли проблеми з плануванням/NUMA.
Виправлення: Перевірте \System\Processor Queue Length і дискові/пам’ятні лічильники. Якщо черга не була високою до зміни — CPU не був лимітатором. Поверніть конфігурацію, якщо це ускладнює NUMA.
4) «Available MBytes низький — в нас немає пам’яті»
Симптом: Низька доступна пам’ять; сигнал тривоги; хтось замовляє RAM.
Коренева причина: Windows агресивно використовує пам’ять під кеш; низька доступна сама по собі не доказ тиску.
Виправлення: Підтвердіть % Committed Bytes In Use і Pages/sec. Низька доступна + високий коміт + тривале сторінкування — це тиск. Низька доступна + низьке сторінкування — може бути нормально.
5) «Сторінкування ненульове — значить погано»
Симптом: Pages/sec показує активність; паніка виникає.
Коренева причина: Сплески сторінкування нормальні; ОС підтискає й керує робочими наборами. Ненульове — це нормально; тривало високий рівень — ні.
Виправлення: Трендіть це. Візьміть 60–120 секунд зразків і зв’яжіть з латентністю і скаргами користувачів.
6) «Get-Counter вихід дивний; числа у науковій нотації»
Симптом: Зі значеннями типу 2.94e+10.
Коренева причина: PowerShell форматує великі числа в наукову нотацію.
Виправлення: Форматуйте вихід явно (наприклад, округлюйте/переводьте одиниці) при звітуванні людям. Не змінюйте спосіб збору; змінюйте спосіб подання.
7) «Лічильники відрізняються між серверами, скрипт зламано»
Симптом: Віддалені запити повертають помилки або відсутні інстанси.
Коренева причина: Імена інстансів різняться (диски, NIC, процеси); ролі/функції змінюють доступні набори лічильників.
Виправлення: Відкривайте PathsWithInstances для кожного хоста перед вибіркою. Уникайте хардкодингу імен інстансів, коли можна опитувати за шаблоном.
8) «Ми вибіркували кожні 60 секунд і нічого не побачили»
Симптом: Користувачі скаржаться на спайки; лічильники спокійні.
Коренева причина: Ви обрали інтервал вибірки, який усереднює проблему.
Виправлення: Використовуйте 1–2 секунди під час триажу, потім розширюйте після того, як зловите сигнатуру.
Контрольні списки / покроковий план
Контрольний список A: Побудуйте базову лінію (зробіть один раз — подякуєте собі пізніше)
- Виберіть 10–15 лічильників для вашої ролі (веб/додаток/БД/файловий сервер). Мінімальний набір:
\Processor(_Total)\% Processor Time\System\Processor Queue Length\Memory\Available MBytes\Memory\% Committed Bytes In Use\Memory\Pages/sec\PhysicalDisk(*)\Avg. Disk sec/Read\PhysicalDisk(*)\Avg. Disk sec/Write
- Збирайте 5–15 хвилин під час відомих «нормально навантажених» періодів, а не о 3 годині ночі, коли нічого не відбувається.
- Зберігайте BLG файли в передбачуваному місці з часовими мітками.
- Документуйте, як виглядає «норма»: типові діапазони латентності, типовий пік CPU і які роботи запускаються коли.
Контрольний список B: Захоплення під час інциденту (мінімальний комплект доказів)
- Запустіть 60–120 секундний захват з інтервалом 1–2 секунди для CPU/пам’яті/латентності диска (Завдання 14, підкоригуйте лічильники при потребі).
- Запишіть, що відчувають користувачі і коли (по хвилинам достатньо).
- Перевірте, чи проблема локальна для хоста чи широка для флоту (Завдання 13).
- Якщо мусите перезапустити щось — робіть це після того, як маєте хоча б один слід.
Контрольний список C: Перетворіть триаж на моніторинг (щоб не переживати один і той самий інцидент знову)
- Створіть заплановане завдання, яке запускає короткий
Get-Counterкаптур під час пікових вікон. - Налаштуйте алерти по трендах, а не по одиночних точках:
- тривала висока латентність диска
- тривале високе використання коміту
- тривале сторінкування при низькій доступній пам’яті
- тривала довжина черги процесора
- Переглядайте щотижня. Не тому, що це весело. Тому що це дешевше за аварії.
Питання й відповіді
1) Чи достатньо Get‑Counter точний для реальної реакції на інциденти?
Так. Воно читає ту саму інфраструктуру лічильників продуктивності, яку використовує PerfMon. Зазвичай точність не є проблемою; проблема — інтерпретація (не той лічильник, не та інстанція, неправильний інтервал).
2) Використовувати CookedValue чи RawValue?
Для більшості операцій користуйтеся CookedValue. RawValue потрібен, коли ви реалізуєте власні обчислення або перевіряєте типи лічильників. У виробничому триазі вам потрібна ясність.
3) Який інтервал вибірки я маю використовувати?
Під час триажу: 1–2 секунди для 30–120 зразків. Для базової лінії: 5–15 секунд протягом 10–30 хвилин. Для довготермінового трендингу: 30–60 секунд підходить, але ви пропустите мікро-спайки.
4) Чому віддалений Get‑Counter падає, коли WinRM працює?
Бо лічильники продуктивності і WinRM — різні «труби». Правила фаєрвола, дозволи, залежності сервісу Remote Registry або посилені політики можуть блокувати збір лічильників, навіть якщо ви можете віддалено підключитися через PowerShell.
5) Чи «Avg. Disk sec/Read» — це те саме, що латентність диска?
Фактично так: це середній час обслуговування на читання в секундах, зафіксований ОС. Множте на 1000, щоб думати в мілісекундах. Відстежуйте як читання, так і запис; вони поводяться по-різному.
6) Яка «хороша» латентність диска?
Залежить від навантаження, але як робоча евристика SRE: одиничні мілісекунди — здорово для багатьох серверних навантажень; десятки мілісекунд — тривожно; сотні — інцидент. Завжди порівнюйте з базовою лінією.
7) Чому CPU виглядає низьким, коли користувачі таймаутять?
Бо очікування — це не CPU. Потоки, заблоковані на диск, мережу, локи або сторінкування, не спалюють CPU. Саме тому дивляться одночасно на чергу процесора, сторінкування і I/O латентність.
8) Чи можна використовувати Get‑Counter як легкий агент моніторингу?
Так, за умови дисципліни. Тримайте невеликий набір лічильників, адекватний інтервал вибірки і структурований вихід (BLG/CSV). Не опитуйте сотні лічильників кожну секунду на продакшн-боксах і не дивуйтеся, коли додали собі навантаження.
9) Як уникнути проблеми «неправильного імені інстансу» для дисків і процесів?
Спочатку перелічіть інстанси через PathsWithInstances, потім опитуйте конкретні шляхи, що повернулися. Для процесів намагайтеся прив’язувати метрики до імен сервісів або ідентифікаторів, коли можливо, бо імена інстансів можуть змінюватися.
Висновок: наступні кроки, які ви реально можете зробити
- Виберіть основні лічильники (CPU total + черга, пам’ять available + commit + pages, латентність чит/запис по томах).
- Запустіть 2-хвилинний захват під час наступної скарги замість того, щоб дивитися в Task Manager. Збережіть як BLG. Докази перш за все, думки потім.
- Приведіть базову лінію для одного «нормально навантаженого» вікна цього тижня. Без базової лінії ви впевнено вгадуєте.
- Перетворіть один урок з інциденту в алерт: тривала латентність диска, тривалий тиск коміту або тривала черга CPU. Оберіть те, що відповідає вашому останньому простою.
- Запишіть ваші пороги як евристики, а не як закони. Ваше середовище підкаже, як виглядає «погано» насправді.
Якщо ви зробите лише одне: почніть регулярно вимірювати латентність диска й тиск коміту. Ці два показники виловлюють дивовижну кількість «таємничих повільних серверів» до того, як вони переростуть у аварії.