opened image

Почему VPS «тормозит»: диагностика производительности

 

Сайт открывается медленно, запросы висят по 5-10 секунд, SSH подключается с задержкой. Причина может быть в CPU, памяти, диске или сети - и каждый случай лечится по-своему. Статья показывает, как за 10-15 минут найти узкое место с помощью стандартных инструментов.

 

 

Первый осмотр: load average

 

Первое, что смотрим при подозрении на тормоза - load average. Он показывает среднее число процессов, ожидающих выполнения, за последние 1, 5 и 15 минут:

 

uptime
# или
cat /proc/loadavg

 

Вывод: 10:23:41 up 12 days, load average: 3.21, 2.87, 1.94

Три числа - среднее за 1 минуту, 5 минут и 15 минут.

 

Нормальное значение load average зависит от числа CPU-ядер. На 2-ядерном VPS load average 2.0 - это полная загрузка. Load average 4.0 на том же сервере означает, что 2 процесса постоянно ждут ресурсов.

 

nproc  # узнать число ядер

 

Правило: если load average за 1 минуту больше числа ядер в 2 раза и при этом значение не снижается (сравни с 15-минутным) - это проблема, а не пик.

 

 

 

 

Шаг 1. CPU - top и htop

 

Открываем top:

top

 

Первые строки после заголовка - состояние CPU:

%Cpu(s): 87.3 us, 5.2 sy, 0.0 ni, 4.1 id, 2.8 wa, 0.0 hi, 0.6 si

 

Ключевые колонки:

  • us (user) - CPU занят пользовательскими процессами

  • sy (system) - CPU в ядре ОС

  • id (idle) - свободен

  • wa (iowait) - CPU ждёт ввода-вывода с диска

 

Если us + sy близко к 100% и id около 0 - CPU перегружен.

Если wa высокий (выше 20-30%) - проблема не в CPU, а в диске.

В top нажимаем P для сортировки по CPU, смотрим топ-3 процесса. Это виновник.

 

htop даёт более наглядную картину с цветовой индикацией по ядрам:

sudo apt install -y htop
htop

 

В htop F6 открывает сортировку, F9 - kill-сигнал выбранному процессу.

 

 

Шаг 2. Память - free и vmstat

 

free -h

 

Вывод:

               total        used        free      shared  buff/cache   available
Mem:           3.8Gi       3.1Gi       142Mi       212Mi       589Mi       461Mi
Swap:          1.0Gi       987Mi        13Mi

 

Смотри на available, а не на free. available - реальная память, доступная для новых процессов, с учётом освобождаемого кэша.

В примере выше: 461 МБ available, Swap используется на 987 МБ из 1 ГБ. Это критическое состояние - сервер активно использует swap, производительность упала в 10-100 раз по сравнению с оперативной памятью.

 

Динамику использования памяти показывает vmstat:

 

vmstat 2 10

 

10 замеров с интервалом 2 секунды. Смотри на колонки:

  • si (swap in) - страницы читаются из swap в RAM

  • so (swap out) - страницы вытесняются из RAM в swap

 

Если si и so ненулевые постоянно - память заканчивается и система активно свапирует.

 

 

Шаг 3. Диск - iotop и iostat

 

Высокий wa в top указывает на I/O bottleneck. Смотрим, кто именно грузит диск:

 

sudo apt install -y iotop
sudo iotop -o

 

Флаг -o показывает только процессы с ненулевой I/O активностью. Типичные виновники: MySQL без query cache при полных table scan, PHP-FPM пишущий логи на каждый запрос, backup-процесс запустился в неудобное время.

 

 

 

Для более детальной статистики по устройствам - iostat:

 

sudo apt install -y sysstat
iostat -x 2 5

 

Ключевая метрика - %util. Значение 100% означает, что диск занят постоянно. На SSD это может быть нормой при высоком IOPS, но на HDD 100% %util - явное узкое место.

Также смотри на await - среднее время ожидания I/O операции в миллисекундах. На SSD нормально < 1-2 мс, на HDD < 10 мс. Значения 50+ мс означают, что очередь на диск переполнена.

 

 

Шаг 4. Типичные виновники

 

PHP-FPM

 

PHP-FPM на пике создаёт много worker-процессов, которые держат память. При нехватке памяти они начинают ждать, запросы копятся.

 

Проверяем статус PHP-FPM:

 

sudo systemctl status php8.3-fpm
# Смотрим на active workers
sudo php-fpm8.3 -t  # проверка конфига

 

Ключевые параметры в /etc/php/8.3/fpm/pool.d/www.conf:

 

pm = dynamic
pm.max_children = 20       ; максимум воркеров
pm.start_servers = 5       ; при старте
pm.min_spare_servers = 2   ; минимум простаивающих
pm.max_spare_servers = 10  ; максимум простаивающих
pm.max_requests = 500      ; рестарт воркера после N запросов (защита от утечек памяти)

 

Для подбора pm.max_children: дели доступную RAM на средний размер одного PHP-процесса. Размер смотри через ps aux | grep php-fpm | awk '{print $6}' | sort -n.

 

 

MySQL

 

Медленные запросы без индексов - частая причина высокого I/O и CPU на MySQL серверах.

 

Включаем slow query log:

SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';

 

Через 10-15 минут анализируем:

sudo mysqldumpslow -s t -t 10 /var/log/mysql/slow.log

 

Покажет топ-10 самых медленных запросов по суммарному времени. Для каждого запускай EXPLAIN в mysql-клиенте - видно, использует ли он индексы.

 

 

Java (Tomcat, Spring Boot)

 

Java-приложения часто «тормозят» из-за GC pause - сборщик мусора останавливает все потоки. Симптом: кратковременные зависания на 1-3 секунды.

 

Смотрим GC логи:

# Для JVM 17+ запусти приложение с флагами:
-Xlog:gc*:file=/var/log/app/gc.log:time,uptime:filecount=5,filesize=20m
grep "GC" /var/log/app/gc.log | tail -20

 

Частые GC с длительностью больше 500 мс - сигнал увеличить heap (-Xmx) или пересмотреть GC-стратегию.

 

 

 

Шаг 5. Сеть

 

Если top и iotop ничего подозрительного не показывают, а тормоза есть - смотрим на сеть.

 

# Трафик по интерфейсам в реальном времени
sudo apt install -y nload
nload eth0

 

Или nethogs для разбивки по процессам:

sudo apt install -y nethogs
sudo nethogs eth0

 

Проверяем потери пакетов:

ping -c 100 8.8.8.8 | tail -3

 

Потери пакетов больше 1% влияют на производительность TCP - браузеры делают retry, задержки накапливаются.

 

 

Шаг 6. Быстрый чеклист диагностики

 

  1. uptime - load average выше числа ядер?

  2. free -h - available < 200 МБ или swap > 50%?

  3. top - wa > 20%? Какой процесс занимает CPU?

  4. sudo iotop -o - кто грузит диск?

  5. vmstat 2 5 - ненулевые si/so?

  6. Логи виновника-процесса: journalctl -u nginx -n 50, /var/log/mysql/slow.log

 

Обычно тормоза укладываются в один из трёх сценариев: заканчивается память и сервер уходит в swap, диск перегружен неоптимальными запросами к БД, или PHP/Java процессы занимают весь CPU из-за неэффективного кода.

 

 

Итог

 

Диагностика производительности VPS - это последовательное сужение подозреваемых: сначала load average и CPU, потом память, потом диск, потом сеть. Инструменты top, htop, free, iotop, iostat и vmstat устанавливаются из пакетов в базовых репозиториях. Всё, что нужно для первичного расследования, есть на любом Linux-сервере без дополнительной установки.