ЯдроКодаподготовка к экзаменам
Учебная платформа

Загружаем материалы

Подготавливаем материалы и навигацию по разделу.

Почему сервер тормозит: USE, PSI и трассировка процесса

Автор: · Обновлено

«Сервер тормозит» становится проверяемой задачей, когда известны операция, задержка и интервал наблюдения. Запишите: какой запрос раньше выполнялся за 100 мс, сколько занимает…

«Сервер тормозит» становится проверяемой задачей, когда известны операция, задержка и интервал наблюдения. Запишите: какой запрос раньше выполнялся за 100 мс, сколько занимает сейчас, затронуты ли все пользователи. Затем ищите ресурс, ожидание которого объясняет симптом. Перезапуск до измерения уничтожает часть доказательств.

Матрица USE за одну минуту

Метод USE предлагает для каждого ресурса проверить загрузку, насыщение и ошибки. Большая загрузка бывает нормальной; насыщение означает, что работа уже ждёт. Запустите ограниченные по времени наблюдения:

uptime
vmstat 1 5
iostat -xz 1 3
pidstat -u -r -d 1 3
cat /proc/pressure/cpu /proc/pressure/memory /proc/pressure/io

iostat и pidstat входят в sysstat. Если утилиты нет, зафиксируйте пробел в наблюдении. Первая строка vmstat обычно отражает средние с загрузки; последующие — заданные интервалы. r характеризует runnable-задачи, b — заблокированные, si/so — движение через swap, st — время, отнятое гипервизором. Существование занятого swap ещё не означает текущую нехватку RAM.

В iostat смотрите await вместе с длиной очереди и интенсивностью операций. %util=100 не доказывает исчерпание пропускной способности любого устройства: SSD, RAID и параллельные очереди нарушают модель одного последовательного диска. Сопоставьте задержку приложения с показателями конкретного устройства. Ошибки ввода-вывода ищут в журнале ядра; сетевые ошибки — в ip -s link. Метод USE, инструменты sysstat.

Высокий load при свободном CPU

Load average учитывает не только готовые к исполнению задачи, но и задачи в непрерываемом ожидании. Высокое число при низком CPU может означать ожидание диска; возможны также ограничения CPU внутри cgroup и неравномерная загрузка ядер. Сравните ps -eo pid,stat,wchan:24,comm, mpstat -P ALL 1 3 и действующие лимиты процесса. Один занятый поток на машине с множеством CPU выглядит небольшой общей загрузкой.

В PSI строка some avg10=12.50 означает долю времени соответствующего окна, когда хотя бы одна задача ждала ресурс. Это не процент используемой памяти. full для поддерживаемых ресурсов означает одновременную остановку всех учитываемых не простаивающих задач; применимость CPU full зависит от области учёта. Рост memory PSI вместе с reclaim и swap гораздо содержательнее одного числа load. Счётчик total накопительный: для интервала нужна разность. Документация PSI.

Память процесса и память системы

ps -eo pid,comm,rss --sort=-rss сортирует RSS в КиБ. Общие страницы могут входить в RSS нескольких процессов; складывать такие числа как независимое потребление неверно. PSS в /proc/PID/smaps_rollup распределяет общие страницы между процессами, отображающими эти страницы. Поля smaps. pmap -x PID помогает найти отображения, а slabtop -o — большие кэши объектов ядра. Доступ к чужим процессам может быть ограничен.

В /proc/meminfo сравнивайте MemAvailable, Slab и Dirty. Большой файловый кэш Linux использует для ускорения чтения и может освобождать при необходимости. Сбрасывать кэш ради красивого free означает менять условия эксперимента и потенциально увеличивать задержки. В контейнере дополнительно изучите memory.current, memory.events и лимиты предков: процесс может получить OOM при свободной памяти хоста.

Найдём причину ENOENT

В отдельном учебном каталоге выполните:

trace_lab=$(mktemp -d)
printf 'port=8080\n' > "$trace_lab/app.conf"
strace -f -e trace=%file -o "$trace_lab/trace.log" \
  cat "$trace_lab/missing.conf"
grep 'missing.conf' "$trace_lab/trace.log"

Ожидаются ненулевой код cat и ENOENT для missing.conf. Многие программы пробуют несколько необязательных путей; наличие любого ENOENT ещё не объясняет сбой. Найдите путь, требуемый именно этой операцией. Для времени вызовов полезны -tt -T, для краткого агрегата — strace -c команда. Подключение к PID требует соответствующих прав и может заметно замедлять процесс. Руководство strace.

ltrace наблюдает доступные ему вызовы библиотечных функций, а strace — границу системных вызовов; статическая линковка и оптимизации влияют на картину ltrace. Для вычислительного узкого места полезнее perf record -g -- команда, затем perf report: ищите горячие стеки, учитывая доступность символов и ограничение perf_event_paranoid. Для уже работающего собственного процесса можно ограничить запись: perf record -g -p PID -- sleep 5.

eBPF-инструменты позволяют агрегировать конкретные события: execsnoop — запуски, opensnoop — открытия файлов, biolatency — задержки блочного I/O. Перед запуском bpftrace проверьте доступность tracepoint и ограничьте длительность. У eBPF тоже есть накладные расходы и требования к правам; фраза «без замедления» не является гарантией.

Задание: при load 12, CPU 20% и растущем io PSI предложите следующий замер, подтверждающий или опровергающий дисковое ожидание. Ответ должен назвать устройство, процесс и временной интервал, а не предлагать немедленно добавить CPU. Механизм выбора потоков объясняет [урок о scheduler](/lessons/without-university/linux-developer-foundations/linux-developer-26).

Короткая проба bpftrace

На учебной VM с bpftrace, доступными tracepoints и нужными правами выполните sudo bpftrace -l 'tracepoint:syscalls:sys_enter_openat', затем:

sudo bpftrace -e 'tracepoint:syscalls:sys_enter_openat /comm == "cat"/ { @opens = count(); } interval:s:3 { exit(); }'

Пока проба работает, в другом терминале вызовите cat /etc/os-release >/dev/null. Через три секунды проба завершится и выведет счётчик наблюдавшихся openat от процессов с comm=cat. Имя comm не уникально; это демонстрация фильтра, а не атрибуция всех событий одному PID. Отсутствие счётчика означает отсутствие подходящих событий, а не обязательно поломку. BPF может быть запрещён lockdown/seccomp/политикой среды; проверьте ошибку, не отключая защиту хоста. Для production нужны более точный фильтр и оценка нагрузки. Язык bpftrace.

Время команды и крупнейшие потребители памяти

Для короткого эксперимента в отдельном shell выполните bash -c 'TIMEFORMAT="real=%R user=%U sys=%S"; time sleep 1'. Real — прошедшее время, user и sys — время CPU в пользовательском и системном режимах. У sleep real будет около секунды, CPU-время близко к нулю; при конкуренции real может быть больше. Встроенный time Bash умеет измерять конвейер, а внешняя /usr/bin/time имеет собственные ключи и область измерения. Не сравнивайте цифры разных запусков без одинаковых данных и условий.

Команда ps -eo pid,comm,rss --sort=-rss | head -n 11 даёт заголовок и десять процессов с наибольшим RSS. Это удобная отправная точка, но общие страницы и момент снимка ограничивают вывод: для объяснения памяти переходите к PSS и cgroup, как показано выше.

Источники