3 сентября 2026 г.

Диагностика Linux-сервера: что делать, когда сервер тормозит

Один разбор вместо десяти вкладок: с чего начать, когда «всё тормозит», как отличить нехватку CPU от дискового I/O и swap, где искать OOM killer и кончившиеся inode, и что приложить к тикету, если дело в хосте.

Сервер тормозит - что делать в первую очередь: не гадать, а за пару минут снять показания. Ниже - порядок действий для Linux (Ubuntu 22.04, 24.04, 26.04 и Debian): сначала общая картина через uptime и top, потом разбор по симптому - процессор, память и swap, дисковый I/O, сеть. Плюс как читать load average, что такое CPU steal и inode, и что приложить к тикету, если окажется, что дело в хосте, а не в вашем коде.

TL;DR. Начните с uptime (load average) и top либо htop. Высокий load при занятом процессоре - смотрите ps aux --sort=-%cpu | head и pidstat 1 5. Высокий load при простаивающем процессоре - ищите процессы в состоянии D (ps -eo state,pid,comm,wchan:32 | grep '^D') и проверяйте диск через iostat -xz 1 (столбцы %utilr_await). Память: free -h (столбец available), vmstat 1 (si/so - активный swap), sudo dmesg -T | grep -i oom - не убивал ли процессы OOM killer. Сеть: ss -s и sudo ss -tlnp. Диск заполнен, но место есть по df -h - проверьте inode через df -i. Часть инструментов не стоит по умолчанию: sudo apt install sysstat iotop htop.

Сервер тормозит - что делать в первые две минуты

uptime показывает три числа load average и время работы без перезагрузки. top - живая таблица процессов плюс строки сводки по процессору и памяти. htop, если он поставлен, - тот же top с цветом, деревом процессов и мышью; на свежем сервере его обычно нет.

uptime
nproc
top

  • uptime - три значения load average (за 1, 5 и 15 минут) и аптайм.
  • nproc - число доступных ядер (vCPU). Load сравнивают именно с ним.
  • top - интерактивный, выход по q. Полезные клавиши: P - сортировка по CPU, M - по памяти, 1 - разбить нагрузку по ядрам.

Что вы должны увидеть. В шапке top - строка %Cpu(s) с полями ussyidwast и строки MiB Mem / MiB Swap. Ниже - процессы. Первым делом читайте строку %Cpu(s): она сразу говорит, во что вы упёрлись - в вычисления (us), в ядро (sy), в диск (wa) или у вас отбирают процессор (st).

Каких инструментов нет в свежей системе

ssjournalctltopfreevmstatpsdfdudmesgswapon обычно уже есть в стандартных образах Ubuntu и Debian (в сильно урезанных cloud- и контейнерных образах может не быть и их). А вот iostatpidstat и mpstat приходят в пакете sysstatiotophtop и, для графика трафика, nload или iftop - отдельными пакетами.

sudo apt update
sudo apt install sysstat iotop htop

nload и iftop ставятся так же, по необходимости. Ставить весь список заранее не обязательно - хватит того, что нужно под конкретный симптом.

Load average: почему load 20 при простое CPU - не парадокс

Load average - усреднённое за 1, 5 и 15 минут число потоков, которые либо выполняются на процессоре, либо стоят к нему в очереди, либо находятся в состоянии непрерываемого сна. D-state (непрерываемый сон) - процесс застрял в системном вызове, обычно на дисковом или сетевом I/O, и не реагирует даже на kill -9, пока операция не завершится. Ключевой момент: в Linux load считает и D-state, а не только процессорную очередь. Поэтому load 20 при почти простаивающем процессоре - это не сломанный датчик, а два десятка процессов, зависших в ожидании медленного диска или сетевой файловой системы.

Как читать три числа: 1-минутное - что происходит сейчас, 15-минутное - тренд. 1-минутное заметно выше 15-минутного - нагрузка растёт; ниже - спад. Ориентир по величине: устойчивый 1-минутный load примерно на уровне числа ядер (nproc), если его создают в основном готовые считать задачи, - все ядра заняты без большой очереди (сверьтесь со строкой %Cpu(s) в top: если велик wa, дело не в процессоре); значительно выше числа ядер - процессы стоят в очереди, и надо понять, за что они борются: за CPU (тогда в top большой us или sy) или за I/O (большой wa, процессы в состоянии D).

Условный пример строки (числа только для иллюстрации): %Cpu(s): 2.0 us, 1.3 sy, 0.0 ni, 8.0 id, 88.0 wa, 0.0 hi, 0.7 si, 0.0 st - процессор почти всё время простаивал при незавершённых операциях ввода-вывода. Load высокий, а виноват не процессор. Большой wa - сильный повод проверить диск, но не приговор именно диску: в состояние D уводит и сетевая файловая система. Список зависших процессов: ps -eo state,pid,comm,wchan:32 | grep '^D'.

Процессор: кто ест CPU и что такое steal

top уже сказал, куда уходит процессорное время. Расшифровка строки %Cpu(s):

  • us (user) - код приложений в пространстве пользователя. Высокий us - какая-то программа реально считает.
  • sy (system) - работа ядра: системные вызовы, переключения контекста, обработка сети. Высокий sy при низком us - подозрительно много системных вызовов (иногда кривой код, иногда шторм пакетов).
  • wa (ожидание ввода-вывода) - доля времени, когда процессор простаивал при незавершённой операции ввода-вывода. Это не занятость процессора, а его вынужденный простой; на многоядерной системе это грубый индикатор, а не точная «доля ожидания диска». Большой wa уводит в раздел про диск.
  • st (steal) - время, когда ваша виртуальная машина была готова считать, но гипервизор не дал ей процессорное время: занял его другими задачами на хосте. Короткие всплески st сами по себе ещё не проблема; устойчивый st, совпадающий по времени с просадкой, - признак того, что хост переподписан. Значения порядка 10% и выше особенно заметны для счётных нагрузок, но универсального порога нет.

ps aux --sort=-%cpu | head
pidstat 1 5

  • ps aux --sort=-%cpu | head - топ процессов по CPU. Оговорка: %CPU здесь - среднее за всё время жизни процесса, недавний всплеск он занижает. Для «прямо сейчас» точнее top или pidstat.
  • pidstat 1 5 - пять замеров с интервалом в секунду, загрузка CPU по процессам в динамике. %usr против %system - то же деление, что us/sy, но по конкретному процессу.

Если высокий именно st, а не us - дело не в вашем коде: гипервизор не выделяет вашему vCPU процессорное время достаточно часто (обычно из-за переподписки хоста), и это уже вопрос к хостеру или тарифу (выделенные ядра, план с гарантированным CPU). Снимите mpstat 1 за несколько минут и приложите к тикету.

Память и swap: когда «тормозит всё» - это своп

free -h - первое по памяти. Значимый столбец - available: сколько памяти приложения могут занять без вытеснения в swap. Столбец buff/cache пугать не должен - это кэш файловой системы, ядро отдаст его под нужды приложений.

swap (раздел или файл подкачки) сам по себе не зло. Проблема - пробуксовка подкачки: оперативной памяти не хватает, и ядро непрерывно гоняет страницы память - диск - память. Формально память есть, но каждое обращение к ней идёт через диск, и сервер замедляется в разы. Со стороны это выглядит как «тормозит вообще всё».

free -h
vmstat 1 5
swapon --show

  • free -h - смотрите available, а не free.
  • vmstat 1 5 - столбцы si и so (подкачка в память и из памяти, КиБ/с). Нули означают, что прямо сейчас обмена со swap нет; сам swap при этом может быть занят - его объём смотрите в столбце swpd, в free -h или swapon --show. Стабильно ненулевые si/so - идёт активная подкачка, вот и тормоза. Ещё столбцы: r - очередь на процессор, b - процессы в непрерываемом сне. Первый отчёт vmstat - средние с момента загрузки; смотрите со второго или запускайте vmstat -y 1 5, чтобы его пропустить.
  • swapon --show - есть ли swap и сколько занято. Пустой вывод - swap не настроен; тогда при нехватке памяти ядро сперва освобождает страничный кэш и другую освобождаемую память, а если и этого мало - вызывает OOM killer.

Если процесс внезапно пропал - без записи в своих логах, без ошибки - вероятно, его убил OOM killer: механизм ядра, который срабатывает, когда запрос памяти нельзя удовлетворить в доступных процессу пределах. Это либо глобальная нехватка ОЗУ и swap, либо лимит памяти cgroup или контейнера (memory.max) - тогда OOM приходит внутри контейнера, даже если на хосте память ещё есть. Жертву ядро выбирает по «badness»-оценке (на неё влияет и oom_score_adj).

sudo dmesg -T | grep -i -E 'oom|killed process'
journalctl -k -b | grep -i 'out of memory'

  • dmesg -T - кольцевой буфер ядра; -T переводит отметки времени в человеческий вид. Нужен sudo: чтение dmesg на Ubuntu по умолчанию закрыто.
  • journalctl -k -b - сообщения ядра за текущую загрузку. Строка вида Out of memory: Killed process 1234 (mysqld) - и есть ответ: кто и когда.

Диск: I/O, заполненный раздел и кончившиеся inode

Здесь два разных вопроса: диск не тянет по скорости - или на диске кончилось место либо inode.

Скорость. iostat -xz 1 - расширенная статистика по устройствам, -z скрывает бездействующие. Первый отчёт - средние с момента загрузки, смотрите второй и дальше.

iostat -xz 1
sudo iotop -o
pidstat -d 1 5

  • iostat -xz 1: столбец %util - доля времени, когда на устройстве была хоть одна операция. Для обычного диска близко к 100% - насыщение; для NVMe %util вводит в заблуждение (устройство держит сотни параллельных операций и показывает 100% далеко не на пределе), поэтому там смотрите r_await / w_await - среднее время чтения/записи в миллисекундах с учётом очереди - и aqu-sz (средняя длина очереди). Десятки миллисекунд на SSD - подозрительно.
  • iotop -o (пакет iotop, запуск от root): -o показывает только процессы, которые прямо сейчас читают или пишут. Объём чтения и записи по процессам он показывает и без дополнительной настройки; а вот колонка процента времени в ожидании ввода-вывода и SWAPIN завязаны на delay accounting, которое на ядрах 5.14+ (все текущие Ubuntu и Debian) по умолчанию выключено. Если эти колонки нужны, временно включите его: sudo sysctl kernel.task_delayacct=1, а после диагностики верните =0 - постоянно держать его включённым смысла нет. Простая альтернатива без настройки - pidstat -d ниже.
  • pidstat -d 1 5 - альтернатива iotop из sysstatkB_rd/s и kB_wr/s по процессам.

Место. df -h - занятость разделов в человеческих единицах. Раздел под 100% - найдите, что распухло:

df -h
sudo du -xh --max-depth=1 / | sort -h

  • du -xh --max-depth=1 / - размер каждого каталога в корне; -x не уходит на другие файловые системы (иначе посчитаете /proc и точки монтирования). Повторяйте вглубь по самому большому каталогу. Обычные виновники - /var/log, кэши, дампы, забытые бэкапы.

Inode. Бывает так: df -h показывает свободные гигабайты, а запись падает с No space left on device. Самая частая причина - закончились inode, записи файловой системы, по одной на каждый файл или каталог (хранят права, владельца, время, указатели на данные). Реже виноваты дисковая квота или лимит контейнера. Число inode на ext4 фиксируется при создании файловой системы и не растёт; XFS выделяет их динамически и в это почти не упирается.

df -i

  • df -i - то же, что df -h, но про inode. IUse% на 100% при свободном месте - типичная картина: миллионы мелких файлов (сессии, письма, кэш, застрявшая очередь задач). Дальше - du --inodes или find по каталогам, чтобы найти источник.

Сеть и соединения: что слушает порт и откуда лавина

ss - штатная замена netstat, ставить ничего не нужно.

ss -s
sudo ss -tlnp
ss -tn state established | wc -l
ss -tn state time-wait | wc -l

  • ss -s - сводка: сколько всего сокетов и сколько TCP в каждом состоянии.
  • ss -tlnp - какие TCP-порты слушаются и каким процессом (t - TCP, l - слушающие, n - без резолва портов в имена, p - процесс; p требует root). Первое, что проверяют, когда «сервис не отвечает»: слушает ли он вообще и на том ли адресе (127.0.0.1 против 0.0.0.0).
  • ss -tn state established | wc -l - число установленных соединений.
  • ss -tn state time-wait | wc -l - соединения в TIME-WAIT (нормальное состояние примерно на минуту после закрытия). Десятки тысяч - высокая текучка соединений; на нагруженном публичном сервисе это может быть нормой. Тревожно, если параллельно кончаются исходящие порты или файловые дескрипторы либо растёт задержка - тогда смотрите keep-alive, пул соединений к базе и характер трафика.

Пропускную способность в реальном времени показывают nload и iftop (оба - отдельные пакеты, iftop запускается от root).

Логи: journalctl, dmesg и где искать упавший сервис

Когда служба отвалилась, ответ почти всегда в логах.

journalctl -p err -b
journalctl -u имя-службы -e
journalctl -f
sudo dmesg -T | tail -n 50

  • journalctl -p err -b - сообщения уровня error и выше за текущую загрузку (-b). Быстрый способ увидеть, что ругалось.
  • journalctl -u имя-службы -e - лог конкретной службы, -e прокручивает в конец. Имя - как в systemctl status (например nginxsshdocker).
  • journalctl -f - хвост журнала в реальном времени; воспроизведите проблему и смотрите, что появляется.
  • dmesg -T - если дело в железе, диске или сети на уровне ядра: ошибки файловой системы, сброс сетевого адаптера, тот же OOM.

systemctl и journalctl в работе можно посмотреть в нашем гайде по настройке веб-сервера Caddy.

Симптом, первая команда, что значит число, вероятная причина

Симптом

Первая команда

На что смотреть

Вероятная причина

Load высокий, реакция вялая

uptimenproc

1-минутный load против числа ядер

load намного выше числа ядер - очередь на CPU или на I/O

Load высокий, но процессор в основном простаивает

top - строка %Cpu(s)

большой wa, процессы в состоянии D

процессы ждут ввода-вывода - чаще диск, иногда сетевая ФС

CPU занят почти на 100%

topps aux --sort=-%cpu | head

какой процесс, us против sy

приложение считает или слишком много системных вызовов

В top большой st

topmpstat 1

устойчивый st, совпадающий с просадкой

хост переподписан - вопрос к хостеру

Всё медленно, диск постоянно шуршит

free -hvmstat 1

available близко к нулю, si/so не по нулям

нехватка памяти, идёт swap

Процесс внезапно исчез

sudo dmesg -T | grep -i oom

строка Out of memory: Killed process

процесс убил OOM killer

df -h показывает место, запись падает

df -i

IUse% = 100%

кончились inode - много мелких файлов

Раздел заполнен

df -hdu -xh --max-depth=1 /

какой каталог распух

логи, кэш, дампы, старые бэкапы

Служба не отвечает по сети

sudo ss -tlnp

слушает ли нужный порт и на том ли адресе

служба упала или слушает 127.0.0.1 вместо 0.0.0.0

Соединений очень много

ss -sss -tn state time-wait | wc -l

десятки тысяч в TIME-WAIT

высокая текучка; проблема, только если кончаются порты/дескрипторы или растёт задержка

Что приложить к тикету в поддержку

Если вы сузили проблему до того, что дело в хосте (высокий st, странные ошибки диска в dmesg, сеть проседает без роста трафика), соберите факты один раз - это экономит круг переписки:

  • окно времени и что значит «тормозит»: конкретный запрос, вход по SSH или вся машина;
  • uptime и nproc;
  • top -b -n1 | head -20 - снимок без интерактива;
  • free -h, а также df -h и df -i;
  • iostat -xz 1 5 - пять замеров;
  • ss -s;
  • относящиеся к делу строки journalctl -p err -b и sudo dmesg -T | tail;
  • при высоком st - mpstat 1 за несколько минут.

CPU steal, ошибки контроллера диска, потери пакетов на шлюзе - это не чинится изнутри виртуальной машины, это зона хостера.

Частые вопросы

Почему load average высокий, а процессор простаивает?

В Linux load average считает не только процессы на CPU и в очереди к нему, но и застрявшие в непрерываемом сне (D-state) - обычно в ожидании диска или сетевой файловой системы. Поэтому load 20 при простаивающем процессоре часто означает не нехватку процессора, а ожидание ввода-вывода - чаще всего диска, иногда сетевой файловой системы. Найдите зависшие процессы (ps -eo state,pid,comm,wchan:32 | grep '^D') и подтвердите по столбцу wa в top и по iostat -xz 1.

Как понять, какой процесс грузит процессор прямо сейчас?

Откройте top и нажмите P (сортировка по CPU) либо запустите pidstat 1 5 для нескольких замеров подряд. ps aux --sort=-%cpu | head тоже даст список, но его %CPU - среднее за всю жизнь процесса, поэтому недавний всплеск он занижает.

Что такое CPU steal на VPS и можно ли с ним что-то сделать?

Steal (столбец st в top) - время, когда ваша виртуальная машина готова считать, но гипервизор занял физическое ядро другим клиентом. Короткие всплески - не проблема; устойчивый st, совпадающий по времени с просадкой, - признак переподписки хоста (порядок 10% и выше особенно заметен для счётных нагрузок). Изнутри виртуальной машины это не лечится: снимайте mpstat 1 и идите к хостеру за выделенными ядрами или другим тарифом.

df показывает свободное место, а файлы не создаются - почему?

Чаще всего кончились inode - служебные записи файловой системы, по одной на файл или каталог. Проверьте df -i: если IUse% равен 100 при свободных гигабайтах, дело в этом (реже - дисковая квота или лимит контейнера). Обычно виноваты миллионы мелких файлов - сессии, кэш, письма, застрявшая очередь задач.

Как узнать, что процесс убил OOM killer?

sudo dmesg -T | grep -i 'killed process' или journalctl -k -b | grep -i 'out of memory'. Строка вида Out of memory: Killed process 1234 (name) с отметкой времени - это он. Причина - ядру не хватило памяти в доступных процессу пределах: глобально (ОЗУ и swap) или по лимиту cgroup/контейнера. Смотрите free -h и что росло по памяти в top; для контейнера - его лимит и memory.current.

Как отличить тормоза из-за swap от обычной нехватки CPU?

Запустите vmstat 1. Ненулевые и не спадающие столбцы si/so - идёт активная подкачка страниц через диск, отсюда общая вялость. При нехватке CPU si/so по нулям, зато растёт столбец r (очередь на процессор) и us/sy в top.

Каких инструментов нет в свежей Ubuntu или Debian?

По умолчанию нет iostatpidstatmpstat (пакет sysstat), а также iotophtopnloadiftop - каждый ставится отдельно. Обычно уже есть в стандартных образах: topfreevmstatpsssjournalctldmesgdfduswapon.

top или htop?

Для разбора «прямо сейчас» разницы почти нет. htop удобнее визуально - дерево процессов, цвета, прокрутка, снятие процесса по F9top есть всегда и умеет пакетный режим (top -b -n1) для снимка в файл или тикет. Ставьте htop для повседневного, top держите как запасной.

Коротко

  • Порядок: сначала uptime и top - общая картина, потом разбор по симптому.
  • Load average в Linux включает процессы в ожидании ввода-вывода (состояние D), поэтому высокий load при простаивающем процессоре - это ожидание ввода-вывода (диск или сетевая ФС), а не нехватка процессора.
  • В строке %Cpu(s)us - приложения, sy - ядро, wa - ожидание ввода-вывода, st - время, отобранное гипервизором.
  • Память смотрят по столбцу available в free -h; активный swap виден в si/so у vmstat 1; убитые процессы - в dmesg по слову oom.
  • Диск: iostat -xz 1 (r_await%util) для скорости, df -h для места, df -i для inode.
  • Сеть: ss -s для сводки, ss -tlnp - кто слушает порт, счёт TIME-WAIT - для оценки текучки соединений.
  • iostatpidstatiotophtopnload ставятся отдельно; ss и journalctl обычно уже на месте.
  • Устойчивый CPU steal и ошибки диска в dmesg - зона хостера: снимите показания и в тикет.
PUBLISHED
3 сентября 2026 г.
AUTHOR
HIP-HOSTING
LANGUAGES
EN · RU