WordPress редко «падает просто так». В большинстве случаев сервер убивает не трафик и не взлом, а фоновые задачи: WP-Cron, Action Scheduler, кеш-прогрев, SEO-аналитика и «умные» плагины, которые в какой-то момент начинают работать одновременно.
В этой статье — реальный кейс: как мы нашли источник фоновой нагрузки, почему сервер падал в одно и то же время, и какие шаги реально помогли стабилизировать систему.
Симптомы проблемы
- Сервер периодически падал без видимой причины
- Нагрузка появлялась не от трафика, а «сама по себе»
- MariaDB ловила OOM Killer
- Пики происходили в одно и то же время
- CPU большую часть времени простаивал
Если процессор свободен, а память заканчивается — почти всегда виноваты фоновые задачи.
Шаг 1. Проверка реальной нагрузки
Смотрим факты, а не ощущения
Первое, что мы сделали — проверили сервер в момент «тишины»:
top
free -h
atop
CPU был почти пустой, но память постепенно съедалась. Это сразу исключило:
- DDoS
- нагрузку от пользователей
- nginx / фронт
Шаг 2. Поиск настоящего виновника
strace и atop показали одно и то же
Через atop и strace стало видно:
- массовые SELECT-запросы
- перебор postmeta, attachment metadata, таксономий
- несколько PHP-FPM процессов одновременно
Это был не фронт. Это был фон WordPress.
Шаг 3. WP-Cron — первый источник хаоса
Почему стандартный WP-Cron опасен
WP-Cron запускается не по времени, а по первому HTTP-запросу. Если задачи копятся — они стартуют все сразу.
define('DISABLE_WP_CRON', true);
После этого мы перевели cron на системный и сделали его управляемым.
Шаг 4. Action Scheduler — главный пожиратель ресурсов
Тысячи фоновых задач — это не норма
WooCommerce и плагины активно используют Action Scheduler. В нашем случае:
| Статус | Количество |
|---|---|
| Выполнено | ~10 000 |
| Неудачно | ~15 000 |
| В ожидании | 16 |
Мы безопасно удалили выполненные и неудачные задачи и оставили только актуальные.
Шаг 5. Ограничение Action Scheduler
Запрещаем лавины задач
Даже после очистки важно не дать очередям снова выйти из-под контроля:
add_filter( 'action_scheduler_queue_runner_concurrent_batches', function () {
return 1;
});
add_filter( 'action_scheduler_queue_runner_batch_size', function () {
return 5;
});
Это превращает хаос в линейную и предсказуемую нагрузку.
Шаг 6. Ограничение PHP-FPM
PHP не должен убивать сервер
pm = dynamic
pm.max_children = 6
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
pm.max_requests = 300
php_admin_value[memory_limit] = 256M
Теперь даже если задача «плохая», она падает сама, а не тянет за собой весь сервер.
Результат
- CPU стабильно на минимальной нагрузке
- Память без резких скачков
- MariaDB перестала ловить OOM
- Фоновые задачи стали предсказуемыми
Главный вывод
WordPress не «тяжёлый» сам по себе. Опасен неконтролируемый фон.
Если:
- отключить стандартный WP-Cron
- ограничить Action Scheduler
- очистить накопившийся мусор
- задать лимиты PHP-FPM
— WordPress спокойно работает даже на небольшом VPS.
Рано радоваться, но теперь сервер живёт своей жизнью, а не по расписанию плагинов.