Диагностика производительности Linux
Диагностика производительности системы — это комплексный процесс анализа ИТ-инфраструктуры (компьютера, сервера, сети или программного обеспечения) для оценки скорости её работы, стабильности и эффективности использования ресурсов. Главная цель этой процедуры — найти «узкие места» (bottlenecks), которые замедляют работу системы, и устранить их до того, как они вызовут сбои или критическое падение скорости.
При диагностике оценивают ключевые метрики использования аппаратных и программных ресурсов:
- Процессор (CPU) — процент общей загрузки, очереди потоков, температура ядер.
- Память (RAM) — объём занятой памяти, наличие утечек, частота использования файла подкачки.
- Дисковая подсистема (I/O) — скорость чтения/записи, длина очереди к диску.
- Сеть — задержки (ping), пропускная способность канала, процент потерянных пакетов.
- Софт и базы данных — скорость тяжёлых SQL-запросов, взаимные блокировки процессов.
Когда хост или сервис тормозит, на машине уже есть встроенные средства — без установки агента и без доступа к исходникам приложения. Эта статья — практический runbook по SSH: что запустить, на что смотреть в выводе и куда копать дальше.
Основные методы проведения диагностики:
- Мониторинг в реальном времени — постоянное наблюдение за метриками (Grafana,
sar,vmstat). - Нагрузочное тестирование — искусственный высокий поток запросов для проверки предела прочности.
- Стресс-тестирование — работа в экстремальных условиях или при нехватке ресурсов.
- Профилирование кода — детальный анализ алгоритмов (
perf, профилировщики языка).
Постоянный мониторинг, алерты и baseline в Grafana — в Мониторинг, метрики и логирование систем — мониторинг. Разбор конкретных инцидентов (сервис не отвечает, D-state, OOM) — в Диагностика и обработка системных ошибок — ошибки и логи. Справочник FHS, chmod и пакетные менеджеры — в Администрирование Linux-систем. Базовые free, df, top — в напоминалке терминала.
Модель USE и порядок действий
Удобная схема для узкого места — USE (Brendan Gregg):
| Буква | Смысл | Вопрос |
|---|---|---|
| U | Utilization | Ресурс занят? (CPU %, %util диска) |
| S | Saturation | Есть очередь? (load, await, swap in/out) |
| E | Errors | Ошибки в ядре, SMART, сеть? |
Метод USE предназначен для быстрого поиска «узких мест» на ранних этапах анализа. Без методологии администраторы часто хаотично проверяют всё подряд; USE сводит лавину метрик к трём вопросам на каждый ресурс и позволяет за 5–10 минут отсечь исправные компоненты.
Порядок анализа внутри USE (не начинайте с графиков utilization):
- Errors — ошибки мгновенно локализуют проблему (сбойный диск, потери пакетов).
- Saturation — длинные очереди при «нормальной» утилизации — главный маркер bottleneck.
- Utilization — показатели близкие к 100 % сигнализируют о дефиците мощности.
Типичный порядок при жалобе «всё медленно» на одном сервере:
- Общая картина за несколько секунд —
vmstat,sarилиmpstat. - Диск —
iostat(высокийiowaitвvmstatчасто ведёт сюда). - Память —
/proc/meminfo, ростsi/soвvmstat. - Сеть и порты —
ss, при конфликте порта —lsof. - Сообщения ядра —
dmesg(OOM, I/O error). - Подозрительный процесс —
/proc/<pid>/status,perf,strace.
USE vs RED. Метод RED (Rate, Errors, Duration) ориентирован на сервисы и приложения — запросы в секунду, ошибки HTTP, latency. USE — на инфраструктуру и ресурсы (CPU, RAM, диск, сеть, лимиты ОС). На одном сервере обычно сначала USE, затем RED для конкретного сервиса.
Обычные системы мониторинга часто показывают только Utilization. Пример ловушки: CPU Utilization 20 %, но Load Average огромен — один поток занял ядро, а 50 процессов стоят в очереди. Без Saturation эту проблему легко упустить.
Установка утилит
Если метод USE — теория и стратегия, то sysstat, perf, strace и lsof — конкретное «оружие» для реализации на практике. Они выстроены по иерархии: от общей картины системы до отдельных syscall и открытых файлов.
| Пакет | Дистрибутив | Даёт |
|---|---|---|
sysstat | Debian/Ubuntu: apt install sysstat | sar, iostat, mpstat, pidstat |
sysstat | RHEL/Alma: dnf install sysstat | то же |
perf | linux-tools-common + метапакет ядра | perf top, perf record |
strace | обычно уже есть | трассировка syscall |
lsof | apt install lsof / в составе системы | открытые файлы и сокеты |
smem | apt install smem | USS/PSS — честный вес процесса |
iotop | apt install iotop | топ процессов по диску |
На Debian для истории sar по расписанию включите сбор: systemctl enable --now sysstat. Логи — /var/log/sysstat/ (Debian) или /var/log/sa/ (RHEL).
Пример связки при тормозах веб-сервера:
iostat/sar— CPU 100 %, диск спокоен.perf top— 80 % времени в функции ядра, связанной с поиском путей.strace -c -p <PID>— миллионыopenat()сENOENT.lsof -p <PID>— приложение долбится в несуществующий путь из конфига.
CPU
sar — срезы загрузки CPU
sar (System Activity Reporter) из пакета sysstat делает мгновенные срезы CPU и читает исторические данные из логов демона sysstat.
Синтаксис: sar [опции] [интервал] [количество]
| Флаг | Назначение |
|---|---|
-u | Загрузка CPU (по умолчанию, если не указан другой отчёт) |
-P ALL | Срез по каждому ядру |
-P 0 | Только ядро №0 |
-q | Load average и длина очереди процессов |
-w | Переключения контекста (cswch/s, proc/s) |
-d | Активность дисков |
-f файл | Читать архив за другой день |
-s HH:MM:SS | Начало интервала в архиве |
-e HH:MM:SS | Конец интервала в архиве |
Мгновенный мониторинг — 5 срезов по 1 секунде:
sar -u 1 5
История за сегодня и за конкретный день:
sar -u
sar -u -f /var/log/sysstat/sa12
sar -u -s 14:00:00 -e 14:30:00
По ядрам (поиск однопоточного bottleneck):
sar -P ALL 1 3
Разбор колонок CPU (связь с USE):
| Колонка | Смысл | USE |
|---|---|---|
%user | Код пользовательских приложений | Utilization |
%system | Работа ядра (syscall, переключения) | Utilization; >30–40 % — аномалия |
%iowait | CPU ждёт диск/сеть | Saturation диска |
%steal | Время «украдено» гипервизором (облако) | Saturation соседей по хосту |
%idle | Простой CPU | Utilization ≈ 100 - %idle |
Если %idle одного ядра 0 %, а остальные ~95 % — однопоточное приложение.
Комбинации после аномалии в sar -u:
- Высокий
%iowait→sar -d 1 5(диски). - Высокий
%system→sar -w 1 5(контекстные переключения).
Пример фрагмента вывода:
14:05:01 CPU %user %nice %system %iowait %steal %idle
14:05:02 all 12.50 0.00 8.25 45.00 0.00 34.25
Average: all 11.20 0.00 7.80 42.10 0.00 38.90
%iowait ≈ 45 % — CPU простаивает в ожидании диска; переходите к iostat и dmesg.
mpstat и pidstat
Дополняют sar на этапе drill-down: mpstat — по ядрам и прерываниям, pidstat — по процессам.
mpstat
mpstat 1 5
mpstat -P ALL 1 3
| Колонка | Смысл | USE |
|---|---|---|
%irq | Аппаратные прерывания | Ошибки/перегруз «железа» на одном ядре |
%soft | Программные прерывания (softirq) | Saturation сетевого стека |
%guest | Время гостевых ВМ (KVM) | Utilization гипервизора |
pidstat
pidstat 1 5 # CPU по процессам
pidstat -u 1 5 # то же явно (-u)
pidstat -d 1 3 # диск: kB_rd/s, kB_wr/s
pidstat -r 1 3 # память: VSZ, RSS, minflt/s, majflt/s
pidstat -w 1 3 # cswch/s, nvcswch/s
pidstat -r -p <pid> 1 # один процесс, динамика памяти
| Сценарий | Что смотреть |
|---|---|
| Кто грузит CPU | %CPU, сортировка по убыванию |
| Кто пишет на диск | kB_wr/s при высоком %util в iostat |
| Утечка / swap | рост RSS, рост majflt/s |
| Нехватка CPU | высокий nvcswch/s |
Связка: mpstat -P ALL показывает ядро 3 на 100 % в %soft → сетевая нагрузка → pidstat -w и pidstat -d находят процесс.
perf top — горячие функции (CPU hotspots)
perf top показывает, какие функции в приложении или ядре сжигают такты CPU. Работает через аппаратные счётчики (сэмплирование), почти без накладных расходов. Нужны права root или настройка kernel.perf_event_paranoid.
sudo perf top
sudo perf top -p <pid>
Колонки вывода:
| Колонка | Смысл |
|---|---|
| Overhead | Доля CPU на функцию; >10–15 % — hotspot |
| Shared Object | [kernel.kallsyms] — ядро; имя бинарника — приложение |
| Symbol | Имя функции |
Типичные hotspots в ядре (высокий %system в sar):
| Symbol | Причина |
|---|---|
_raw_spin_lock, mutex_spin_on_owner | Lock contention, много потоков |
ext4_*, vfs_*, generic_file_read_iter | Интенсивный дисковый I/O через ядро |
ipt_do_table, nf_hook_slow | Файрвол при сетевом флуде |
В приложении: __memcmp_avx2, memcpy — копирование больших массивов; в PostgreSQL TupleSatisfiesSnapshot — full table scan без индекса.
Интерактив: стрелки → Enter → Annotate — ассемблер/исходник с долей нагрузки по строкам.
Если вместо имён — адреса 0x00007f…, нужны debug-символы (nginx-dbgsym) или perf-map для JIT (Java, Node.js).
sudo sysctl -w kernel.perf_event_paranoid=-1 # временно, если perf отказал в доступе
Запись профиля и Flame Graph:
sudo perf record -F 99 -g -p <pid> -- sleep 10
sudo perf report
# perf script | stackcollapse-perf.pl | flamegraph.pl > hotspot.svg
| Симптом в CPU | Куда дальше |
|---|---|
Высокий %iowait | Диск |
| Один процесс 90 %+ | perf top -p, pidstat |
| Много потоков, умеренный CPU | /proc/<pid>/status, блокировки в приложении |
Память
/proc/meminfo — детали от ядра
Виртуальный интерфейс к ядру: более 40 строк метрик RAM и swap. Точнее, чем free.
cat /proc/meminfo
egrep '^MemTotal|^MemAvailable|^SwapFree|^Slab|^AnonPages' /proc/meminfo
Ключевые поля (USE):
| Поле | Смысл | USE |
|---|---|---|
MemTotal | Вся физическая RAM | — |
MemFree | Абсолютно свободная RAM (мало значит в Linux) | — |
MemAvailable | Сколько реально отдать приложениям | Saturation; →0 — риск OOM |
Buffers | Кэш сырых блоков диска | Utilization |
Cached | Page cache файлов | Связь RAM ↔ диск |
Active / Inactive | Недавно / давно использованная память | Кандидаты на вытеснение |
SwapTotal / SwapFree | Объём swap | Saturation при падении SwapFree |
Shmem | Shared memory, tmpfs (/run, /tmp) | Скрытый потребитель |
Slab | Структуры ядра | — |
SReclaimable / SUnreclaimable | Освобождаемая / «вечная» slab | Рост SUnreclaimable — утечка в ядре |
AnonPages | Память приложений (heap, stack) | Рост при стабильной нагрузке — leak |
Dirty | Страницы, ещё не сброшенные на диск | Тяжёлая запись |
Полный справочник полей — Справочник по Linux — /proc.
vmstat — своп, очереди, контекстные переключения
Один снимок всей системы: процессы, память, swap, I/O, CPU.
vmstat 1 5
vmstat -S M 1 5 # память в мегабайтах
vmstat -s # накопленная статистика списком
vmstat -d # статистика по дискам
Структура строки вывода:
procs -----------memory---------- ---swap-- ---io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
2 0 0 120432 2048 543204 0 0 12 45 120 450 15 5 78 2 0
| Блок | Колонки | USE |
|---|---|---|
| procs | r — runnable (очередь на CPU); b — blocked (ждут I/O, D-state) | Saturation |
| swap | si swap in, so swap out (Кб/с) | Saturation; постоянный поток — thrashing |
| memory | swpd, free, buff, cache | Utilization |
| io | bi/bo — блоки read/write в секунду | Нагрузка на диск |
| system | in — прерывания; cs — context switches | Saturation при миллионах cs/с |
| cpu | us, sy, id, wa (iowait), st (steal) | Utilization / Saturation |
Диагноз «дисковый затуп»: b растёт, so/bi/bo высокие, wa зашкаливает → Диск и dmesg.
Память одного процесса
PID: pidof имя или pgrep имя.
RSS vs VSZ
| Метрика | Смысл |
|---|---|
| VSZ (VIRT) | Вся запрошенная виртуальная память (mmap, библиотеки, неиспользуемый heap) |
| RSS (RES) | Реально занятая физическая RAM — ориентир «прожорливости» |
grep -E 'VmSize|VmRSS|RssAnon|RssFile|VmSwap|Threads' /proc/<pid>/status
| Поле | Смысл |
|---|---|
VmRSS | Физическая RAM процесса |
RssAnon | Анонимная RAM (heap); рост во времени — leak |
RssFile | Файлы в page cache; легко освобождается |
VmSwap | Процесс в swap — сильные тормоза |
Threads | Число потоков |
pidstat -r — динамика и page faults:
pidstat -r -p <pid> 1
majflt/s растёт — процесс лезет в swap.
pmap — карта памяти по сегментам:
pmap -x <pid>
pmap -X <pid> | sort -nk 3 | tail -15 # ТОП-15 сегментов
smem — честный вес с учётом shared libraries:
smem -P postgres -u -k # USS и PSS в килобайтах
| Метрика | Смысл |
|---|---|
| USS | Уникальная память процесса |
| PSS | USS + доля shared; лучший итог для системы |
Утечки и OOM в сценариях — Диагностика и обработка системных ошибок — память и OOM.
Диск
iostat — I/O и загрузка устройств
Главный инструмент USE для дисков. Первый вывод после запуска — среднее с boot; для диагностики нужен интервал.
iostat -xz 1
iostat -x -z 1 5
| Флаг | Назначение |
|---|---|
-x | Расширенные поля (await, aqu-sz, IOPS) |
-z | Скрыть idle-устройства |
-m | Килобайты → мегабайты |
Ключевые колонки:
| Поле | Смысл | USE |
|---|---|---|
%util | Время, когда к устройству был хотя бы один запрос | Utilization; ~100 % — на пределе |
aqu-sz (или avgqu-sz) | Средняя длина очереди | Saturation; >2–5 на один диск — пробка |
await | Среднее время I/O (очередь + выполнение), мс | Saturation; NVMe <1 мс, SSD 3–5 мс, HDD до 15–20 мс |
r/s, w/s | Операции чтения/записи в секунду (IOPS) | Характер нагрузки |
rkB/s, wkB/s | Пропускная способность | Большие файлы vs мелкий random I/O |
Пример подозрительной строки:
Device r/s w/s rkB/s wkB/s await aqu-sz %util
sdb 1200 5.00 4800.00 20.00 85.50 12.40 100.00
Анализ: %util 100 %, aqu-sz 12 — очередь; await 85 мс — приложения ждут; rkB/s/r/s ≈ 4 КБ — random read мелкими блоками (типично для full scan БД).
Связка после iostat:
pidstat -d 1— какой PID генерирует I/O.iotop— живой топ по диску.dmesg— аппаратные I/O errors vs чистая перегрузка.
Высокий %util при малом throughput — мелкий random I/O или деградирующий диск — Диагностика и обработка системных ошибок — аппаратная диагностика.
Сеть и порты
ss — listening-порты, очереди, соединения
Современная замена netstat; данные через netlink. Быстра на хостах с миллионами сокетов.
sudo ss -tulpn
sudo ss -tulpn | grep :8080
ss -ltn
ss -t state established
ss -t dst 192.168.1.50
ss -ti # RTT, таймауты TCP
| Флаг | Назначение |
|---|---|
-t | TCP |
-u | UDP |
-l | Только listening |
-p | PID и имя процесса (нужен sudo) |
-n | Числовые порты/IP (быстрее, без DNS) |
Очереди listening-сокетов (ss -ltn):
| Колонка | В режиме LISTEN |
|---|---|
| Recv-Q | Число соединений, прошедших handshake, но не принятых приложением (accept) |
| Send-Q | Размер backlog (макс. очередь) |
Если Recv-Q ≈ Send-Q — приложение не успевает принимать соединения (Saturation); клиенты получают отказы или задержки.
Аудит «что слушает хост» — Сетевые подключения и диагностика — справочник при сбоях.
lsof — кто занял порт и открытые файлы
В Linux сокеты — тоже «файлы».
sudo lsof -i :80
sudo lsof -i tcp:3000
sudo lsof -i udp:53
sudo lsof -t -i :8080 # только PID
sudo kill -9 $(sudo lsof -t -i :8080)
sudo lsof -i :8000-8010
sudo lsof -p <pid> # все FD процесса
sudo lsof +D /var/log # кто держит файлы в каталоге
| Колонка | Смысл |
|---|---|
| COMMAND | Имя процесса |
| PID | Идентификатор |
| FD | Дескриптор (IPv4, IPv6) |
| NAME | *:http (LISTEN) и т.п. |
ss vs lsof: ss быстрее на перегруженных системах; lsof точнее для Unix-сокетов, pipe и лимита «Too many open files».
Пропускная способность и задержки — iftop, nethogs, iperf3 (Сетевые подключения и диагностика).
Ядро — dmesg
Буфер сообщений ядра (kernel ring buffer). Основной источник Errors на низком уровне.
sudo dmesg -T
sudo dmesg -Tw # follow, как tail -f
sudo dmesg -T -l err,crit,alert,emerg
sudo dmesg -T | grep -Ei 'kill|error|fail|throttled|full|drop' | tail -20
| Флаг | Назначение |
|---|---|
-T | Человекочитаемые дата и время |
-w | Вывод новых сообщений в реальном времени |
-l | Фильтр по уровню (err, crit, …) |
Что искать:
| Маркер в логе | Значение |
|---|---|
Out of memory: Kill process | OOM Killer — Saturation RAM |
I/O error, blk_update_request | Аппаратный сбой диска, не просто нагрузка |
nf_conntrack: table full | Переполнение таблицы соединений — Errors сети |
NETDEV WATCHDOG, link down | Сеть / драйвер |
throttled, temperature above threshold | Троттлинг CPU от перегрева |
Для systemd: journalctl -k --since "1 hour ago".
dmesg фиксирует то, что сообщило ядро. Ошибки уровня HTTP, SQL или бизнес-логики ищите в journalctl -u … и файлах в /var/log/ — см. Диагностика и обработка системных ошибок.
Отладка процесса без исходников
strace — системные вызовы
Перехватывает syscall процесса. Через ptrace сильно замедляет приложение — на проде только с фильтрами и кратко.
sudo strace -p <pid>
strace ./app arg1
sudo strace -c -p <pid> # сводная статистика; Ctrl+C
sudo strace -c -T -p <pid> # + время на вызов
sudo strace -T -y -p <pid> # -y: пути файлов вместо fd
sudo strace -T -e trace=openat,read,write -p <pid>
sudo strace -e trace=network -p <pid>
sudo strace -o trace.log -f ./app # -f: дочерние процессы
| Флаг | Назначение |
|---|---|
-p PID | Подключиться к процессу |
-c | Таблица: вызовы, % time, errors |
-T | Время каждого вызова в конце строки |
-e trace=… | file, network, desc, signal |
-y | Расшифровка fd → путь или сокет |
-f | Следить за fork |
Примеры разбора:
openat(..., "/etc/config.json", ...) = -1 ENOENT (No such file or directory)
Миллионы ENOENT — цикл по несуществующему пути; Errors.
futex(..., FUTEX_WAIT_PRIVATE, ...) # или epoll_wait без таймаута
Процесс ждёт блокировку или сеть — Saturation, CPU свободен.
write(3</var/log/big.log>, ..., 4096) = 4096 <0.125430>
125 мс на 4 КБ — код в порядке, тормозит диск.
strace и полный perf record замедляют процесс. Сначала pidstat, vmstat, затем strace -c на 5–10 секунд или на staging.
perf и lsof в разборе процесса
perf top -p <pid>— hotspots CPU (подробно в разделе CPU).lsof -p <pid>— все открытые файлы, сокеты, лимит FD приToo many open files.
Для Java/.NET — jstat, dotnet-counters (Диагностика и обработка системных ошибок — диагностика по приложению).
Сводная таблица команд
| Ресурс | Команда | Зачем |
|---|---|---|
| CPU | sar -u 1 5, sar -P ALL 1 | Загрузка, iowait, по ядрам |
| CPU | sar -q 1, sar -w 1 | Load, context switches |
| CPU | mpstat -P ALL 1 | %irq, %soft по ядрам |
| CPU (процесс) | pidstat 1, pidstat -w 1 | Кто грузит CPU, cswch |
| CPU (hotspots) | perf top -p <pid> | Горячие функции |
| Память | egrep … /proc/meminfo | MemAvailable, AnonPages, Slab |
| Память (динамика) | vmstat 1 5, vmstat -S M 1 | r/b, si/so, wa, cs |
| Память (процесс) | /proc/<pid>/status, pidstat -r -p <pid> 1 | RSS, swap, majflt |
| Память (карта) | pmap -x <pid>, smem -P app -u -k | Сегменты, USS/PSS |
| Диск | iostat -xz 1 | %util, aqu-sz, await |
| Диск (процесс) | pidstat -d 1, iotop | Кто пишет/читает |
| Сеть | ss -tulpn, ss -ltn | Порты, Recv-Q/Send-Q |
| Порт | lsof -i :<port> | Конфликт порта |
| Ядро | dmesg -T, dmesg -T -l err,crit | OOM, I/O, throttling |
| Процесс | strace -c -T -p <pid> | Зависания, ENOENT, I/O |
| Файлы процесса | lsof -p <pid> | FD, утечки сокетов |
Когда CLI недостаточно
| Ситуация | Следующий шаг |
|---|---|
| Нужен тренд за неделю | Мониторинг, метрики и логирование систем — метрики и мониторинг, Prometheus/node_exporter |
| Распределённая система | Трассировка (OpenTelemetry, Jaeger), correlation ID в логах — Диагностика и обработка системных ошибок — сценарий latency |
| Только один запрос тормозит | Логи приложения, профилировщик языка, БД (EXPLAIN, slow query) |
| Хост в облаке | Метрики провайдера + те же команды на ВМ |
Дальше
| Цель | Материал |
|---|---|
| Типовые инциденты и runbook | Диагностика и обработка системных ошибок |
Сеть, curl, tcpdump | Сетевые подключения и диагностика |
/proc, sysctl | Справочник по Linux |
| Мониторинг и алерты | Мониторинг, метрики и логирование систем |
| Права, systemd, пакеты | Администрирование Linux-систем |
| Чек-лист раздела | Системное администрирование — чек-лист |