«Сервер тормозит» — в 9 случаях из 10 это один конкретный процесс, который съел процессор или память. Найти его — минутное дело, если знать три команды: ps, top и htop. Разберём на живых примерах, без теории ядра Linux.
Что такое процесс — своими словами
Процесс — это любая запущенная программа: веб-сервер nginx, база данных MySQL, ваш Python-скрипт. У каждого есть PID (номер), владелец и счётчики ресурсов. Когда сервер «тормозит», задача одна: найти процесс с аномальным аппетитом.
htop: самый удобный способ
Если htop не установлен: sudo apt install htop. Запуск — просто htop.

Как читать: сверху — полоски загрузки каждого ядра CPU и памяти, снизу — таблица процессов. Управление клавишами: F6 — сортировка (выберите CPU% или MEM%), F4 — фильтр по имени, F9 — завершить выбранный процесс, q — выход. Первая строка после сортировки по CPU% — ваш подозреваемый.
ps: когда нужен разовый снимок
Классика для скриптов и быстрых проверок:
ps aux— все процессы системы одной простынёй;ps aux --sort=-%cpu | head -10— ТОП-10 по процессору;ps aux --sort=-%mem | head -10— ТОП-10 по памяти;ps aux | grep nginx— найти конкретную программу и её PID.
В выводе смотрите колонки %CPU, %MEM и STAT (буква Z — «зомби», D — процесс завис на диске).
Как завершить зависший процесс
Сначала вежливо (процесс успеет корректно закрыться):
kill PID
Не помогло через 10–15 секунд — жёстко:
kill -9 PID
Всех тёзок разом: pkill -f myscript.py. ⚠️ Перед kill -9 для баз данных подумайте дважды: жёсткое убийство MySQL посреди записи может повредить таблицы — сначала попробуйте systemctl restart mysql.
Типовые диагнозы
- mysqld ест 100% CPU — почти всегда тяжёлые запросы без индексов: смотрите slow query log;
- Много процессов php-fpm и кончилась память — уменьшите pm.max_children или добавьте RAM;
- Незнакомый процесс с случайным именем грузит CPU — плохой знак: возможно, на сервер попал майнер. Проверьте автозагрузку, смените пароли;
- kswapd0 в топе — память кончилась, система живёт в свопе: пора на тариф побольше. Если апгрейд VPS уже не помогает — смотрите мощные выделенные серверы.
systemctl: когда процесс — это сервис
nginx, MySQL, php-fpm — не просто процессы, а сервисы под управлением systemd. Управлять ими правильнее не через kill, а так:
systemctl status nginx— жив ли, сколько памяти ест, последние строки лога;systemctl restart nginx— корректный перезапуск;systemctl enable nginx— автозапуск после перезагрузки сервера (частая причина «после ребута сайт не поднялся» — это забытая команда);journalctl -u nginx -n 50— последние 50 строк лога сервиса, когда ищете причину падения.
Если процесс падает регулярно
Убивать симптом бесполезно — нужна автоматика и причина. Во-первых, скажите systemd поднимать сервис самому: в юните пропишите Restart=always и RestartSec=5. Во-вторых, найдите закономерность: journalctl -u имя_сервиса --since today покажет время каждого падения — если оно совпадает с пиками трафика или бэкапом, диагноз почти готов. Самая частая причина внезапных смертей — OOM killer: системе не хватило памяти, и ядро убило самый прожорливый процесс. Проверяется командой dmesg | grep -i oom. Если OOM стал регулярным — оптимизируйте потребление или добавляйте RAM.
Чтобы скрипт не умирал после выхода из SSH: nohup, screen, tmux
Боль каждого новичка: запустил парсер, закрыл ноутбук — процесс умер. Так происходит потому, что процессы привязаны к SSH-сессии. Три решения по нарастающей:
- nohup — самый простой:
nohup python3 bot.py &— процесс отвязан от сессии, вывод пишется в nohup.out; - screen / tmux — «виртуальный терминал», который живёт на сервере:
tmux new -s bot→ запускаете скрипт → отцепляетесь Ctrl+B, D → возвращаетесь позже командойtmux attach -t botи видите живой вывод; - systemd-сервис — правильный вариант для постоянных программ: авто-старт после перезагрузки, автоперезапуск при падении, логи в journalctl. Один раз написать юнит — и забыть про nohup навсегда.
Зомби и сироты: страшные слова, нестрашные явления
В выводе ps со STAT=Z живут процессы-зомби — уже завершившиеся, но не «похороненные» родителем записи в таблице процессов. Ресурсов они не едят, убить их kill нельзя (они уже мертвы) — исчезнут сами, когда родительский процесс заберёт их статус или завершится. Один-два зомби — норма; сотни — баг в приложении-родителе, лечится его перезапуском. Сироты — процессы, чей родитель умер раньше: их усыновляет init/systemd, и они спокойно работают дальше. Паниковать не о чем — это штатная механика Linux.
Частые вопросы
Чем top отличается от htop?
top предустановлен везде, но аскетичен; htop — цветной, с мышкой, сортировкой в два нажатия и наглядными полосками ядер. На своём сервере ставьте htop, top держите как запасной вариант «когда ничего нельзя устанавливать».
Что такое load average?
Три числа в top/htop — средняя очередь задач за 1, 5 и 15 минут. Практическое правило: load выше числа ядер — сервер не справляется. У VPS на 2 ядра load 4.0 означает двукратную перегрузку.
Как посмотреть, кто ест диск, а не CPU?
sudo iotop — тот же топ, но по дисковым операциям. Медленный диск маскируется под «тормозит всё»: если у тарифа HDD — переезд на NVMe решает проблему радикальнее оптимизаций.
Как найти процесс, занявший порт?
ss -tlnp | grep :8080 — в конце строки будет имя и PID. Классика применения: «Address already in use» при запуске приложения — старый экземпляр не умер, находите его этой командой и завершаете.
Как ограничить прожорливый процесс, не убивая?
Понизить приоритет CPU: renice +10 -p PID — процесс продолжит работать, но начнёт уступать остальным. Для сервисов правильнее лимиты systemd: строки CPUQuota=50% и MemoryMax=1G в юните жёстко ограничат аппетиты навсегда.
Что значит высокий %wa в top?
Процессор простаивает в ожидании диска: узкое место не CPU, а дисковая подсистема. Смотрите iotop, и если у тарифа обычный SSD или HDD — переезд на NVMe даст больше, чем любые оптимизации кода.
Шпаргалка: команды из гайда
| Задача | Команда |
|---|---|
| Интерактивный монитор | htop (F6 — сортировка, F9 — kill) |
| ТОП по CPU | ps aux --sort=-%cpu | head |
| ТОП по памяти | ps aux --sort=-%mem | head |
| Найти по имени | ps aux | grep nginx |
| Найти по порту | ss -tlnp | grep :80 |
| Завершить мягко / жёстко | kill PID / kill -9 PID |
| Статус сервиса | systemctl status nginx |
| Лог сервиса | journalctl -u nginx -n 50 |
| Кто ест диск | sudo iotop |
| Жертвы OOM | dmesg | grep -i oom |
Мини-кейс: «сайт тормозит» — полный проход за 5 минут
Соберём команды гайда в связный сценарий. Жалоба: сайт на VPS открывается по 10 секунд.
htop— смотрим общую картину. Load average 5.2 при 2 ядрах — сервер перегружен в 2,5 раза. Сортируем по CPU%: наверху mysqld с 140%;- Значит, дело в базе.
sudo mysqladmin processlist(или SHOW PROCESSLIST в консоли MySQL) — видим один SELECT, висящий 400 секунд; - Параллельно проверяем память: в htop Swp заполнен — система свопится, что добивает диск.
dmesg | grep -i oom— ядро уже дважды убивало php-fpm ночью; - Диагноз двойной: тяжёлый запрос без индекса + нехватка RAM. Лечение: добавить индекс (быстро) и переехать на тариф с большей памятью (системно);
- Контроль после: load вернулся ниже 2, Swp пустой, страницы отдаются за полсекунды.
Обратите внимание на логику: мы не «перезагрузили сервер и надеемся» — каждая команда сужала круг, и через пять шагов у проблемы появились имя и решение. Этот же маршрут работает почти для любых тормозов.
Итог
Алгоритм на память: htop → F6 → сортировка по CPU% или MEM% → нашли виновника → чините причину или kill. Если после всех чисток load стабильно выше числа ядер — это не проблема, а рост: пора на конфигурацию мощнее.