Если сайт, который ещё вчера работал быстро, сегодня открывается медленно, панель долго грузится или мониторинг сообщает, что сервер не отвечает, первое подозрение падает на нагрузку. В панике сразу увеличить тариф или перезагрузить сервер — чаще всего неверное решение: причина никуда не уходит, и через несколько часов проблема возвращается. Правильный путь — выяснить, что именно создаёт нагрузку. Пять шагов ниже написаны для владельцев VPS, но их логика работает и на обычном хостинге: там часть сведений можно получить через панель или поддержку.
Шаг 1: действительно ли нагрузка высокая
Начните с цифр. Команда uptime показывает среднюю нагрузку (load average) за последние 1, 5 и 15 минут. Это число имеет смысл только в сравнении с количеством ядер процессора: на 4-ядерном сервере нагрузка около 4 означает полную занятость, а 20 говорит о серьёзной очереди. Число ядер покажет nproc.
uptime
nproc
free -h
df -h
free -h показывает состояние памяти и swap: если свободной памяти почти не осталось, система может принудительно завершать процессы. df -h проверяет диск. Переполненный диск останавливает запись логов, работу базы и сессии, и сайт тоже начинает тормозить. Иногда то, что принимают за нагрузку, на деле оказывается заполненным диском.
Шаг 2: какой процесс съедает ресурсы
top или htop в реальном времени показывают процессы, которые больше всего используют процессор и память. Для разового списка удобнее ps:
ps aux --sort=-%cpu | head -15
ps aux --sort=-%mem | head -15
Посмотрите, кто наверху. Множество процессов php-fpm или httpd говорит о большом трафике на сайт. Если вверху mysqld, значит, выполняются тяжёлые запросы. Если в списке незнакомый процесс со странным именем или запущенный из /tmp держит процессор на 100%, это может быть майнер криптовалюты. Такой процесс нужно остановить сразу, а затем выяснить, как он появился, потому что обычно он восстанавливает себя через cron.
Если процессор почти свободен, а нагрузка всё равно высокая, проблема может быть в диске. Высокое значение wa (iowait) в top означает, что процессы ждут ответа от диска. В этом случае iotop покажет процесс, который пишет на диск больше всех.
Шаг 3: кто заходит на сайт
Часто причина роста нагрузки находится снаружи: поисковые боты, AI-краулеры, скрипты подбора паролей или обычный DDoS. Из access-лога веб-сервера можно вывести самые активные IP-адреса и запрашиваемые страницы:
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -20
awk -F'"' '{print $6}' access.log | sort | uniq -c | sort -rn | head -10
grep -c "wp-login.php" access.log
Первая команда показывает IP с наибольшим числом запросов, вторая — названия браузеров и ботов (User-Agent), третья — сколько раз обращались к странице входа. Например, у интернет-магазина в Ташкенте нагрузка за одну ночь выросла в десять раз, и по логу выяснилось, что один бот перебирает страницы фильтров каталога в тысячах комбинаций. Закрытие адресов фильтров в robots.txt и ограничение бота вернули нагрузку в норму за несколько минут.
Если один IP-адрес отправляет сотни запросов в минуту и не принадлежит известной поисковой системе, его можно временно заблокировать. В Apache 2.4 это делается через .htaccess так, а на VPS эффективнее блокировать на уровне файрвола:
<RequireAll>
Require all granted
Require not ip 203.0.113.50
</RequireAll>
Шаг 4: cron и фоновые задачи
Если нагрузка растёт каждый день в одно и то же время, например ночью или в начале часа, скорее всего, виновата плановая задача: резервное копирование, импорт, индексация сайта или рассылка. Посмотрите список cron текущего пользователя:
crontab -l
ls /etc/cron.d/
На сайтах WordPress wp-cron.php запускает фоновые задачи при каждом посещении и при большом трафике создаёт лишнюю нагрузку. Обычно намного легче отключить его и вызывать через настоящий cron. Для этого в wp-config.php добавляется строка define('DISABLE_WP_CRON', true);, а в cron прописывается задача с запуском раз в 5 или 15 минут.
Проверьте также, не работают ли параллельно несколько копий одной задачи. Если следующий запуск начинается до завершения предыдущего, число процессов быстро растёт и заполняет память. Чтобы этого избежать, команду в cron можно обернуть в flock.
Шаг 5: тяжёлые запросы к базе данных
Если наверху держится mysqld, нужно увидеть, какие именно запросы выполняются. В консоли MySQL или MariaDB следующая команда выводит все текущие запросы:
mysql -e "SHOW FULL PROCESSLIST;"
Если один и тот же запрос повторяется десятки раз и долго висит в состоянии «Sending data» или «Locked», скорее всего, в таблице не хватает индекса или плагин отправляет крайне неэффективный запрос. Для долгосрочного анализа полезно включить журнал медленных запросов (slow query log): он записывает запросы, выполнявшиеся дольше заданного времени, и их можно разобрать позже.
Зафиксируйте результат
Когда причина найдена, кратко запишите её: когда началось, какой процесс или IP, как решили. Если ситуация повторится, это сэкономит время. Если у вас обычный хостинг и выполнить серверные команды вы не можете, обратитесь в поддержку через кабинет sayt.uz и укажите, когда выросла нагрузка: по серверным логам причину можно будет установить.