В WordPress есть свой планировщик задач, WP-Cron. Через него работают отложенные публикации, проверка обновлений, рассылки, бэкапы и задачи плагинов. Но это не настоящий cron. WP-Cron запускается, только когда кто-то открывает сайт.
Как работает WP-Cron
При каждом открытии страницы WordPress проверяет, нет ли задач, время которых пришло. Если есть, он
отправляет запрос сам себе на wp-cron.php, и задачи выполняются в этом запросе.
Отсюда и проблемы:
- Мало посетителей — задачи опаздывают. Если ночью на сайт никто не заходит, задача на 03:00 выполнится утром, с первым посетителем.
- Кэш страниц — задачи не запускаются. Если страницы отдаёт кэширующий плагин, nginx или CDN, запрос до PHP не доходит, и WP-Cron не срабатывает.
- Много посетителей — лишняя нагрузка. На загруженном сайте проверка идёт при каждом открытии страницы.
- Сайт закрыт от самого себя. Если сервер не может открыть свой же адрес (файрвол, базовая авторизация,
неправильный DNS), запрос к
wp-cron.phpне проходит, и задачи не выполняются вообще.
Самый заметный симптом — запись с пометкой «Missed schedule» («Пропущено по расписанию»). Отложенная публикация не вышла, потому что в нужный момент WP-Cron не запустился.
Как перевести WP-Cron на системный cron
Надёжнее отключить запуск WP-Cron при открытии страниц и запускать его по расписанию из системного cron.
Шаг 1. Отключить запуск при посещениях
Добавьте в wp-config.php строку выше комментария /* That's all, stop editing! */:
define('DISABLE_WP_CRON', true);
Сами задачи при этом никуда не денутся, просто их перестанут запускать при открытии страниц.
Шаг 2. Запускать WP-Cron из системного cron
Если на сервере есть WP-CLI, запускайте задачи им:
*/5 * * * * cd /var/www/site && /usr/local/bin/wp cron event run --due-now > /dev/null 2>&1
Без WP-CLI можно запускать wp-cron.php через PHP напрямую:
*/5 * * * * cd /var/www/site && /usr/bin/php wp-cron.php > /dev/null 2>&1
На виртуальном хостинге без доступа к консоли задачу cron обычно добавляют в панели управления. Там часто
можно указать только адрес, тогда используйте запрос к wp-cron.php:
*/5 * * * * wget -q -O /dev/null "https://site.ru/wp-cron.php?doing_wp_cron"
Каждые 5 минут хватает почти всем сайтам. Задачи, время которых пришло между запусками, выполнятся в следующий запуск.
Шаг 3. Проверить
С WP-CLI посмотреть задачи и время их следующего запуска можно так:
wp cron event list
Если в колонке next_run_relative много задач с прошедшим временем, они не выполняются. Без консоли
задачи видно в плагине WP Crontrol.
Как узнать, что WP-Cron выполняется
После перевода на системный cron WordPress зависит от того, работает ли cron на сервере. Если строку удалят при переезде или сервер перестанет её запускать, публикации снова начнут пропускаться, и сообщения об этом не будет.
Чтобы узнавать сразу, добавьте в строку cron запрос к Steadrun после выполнения задач:
*/5 * * * * cd /var/www/site && /usr/local/bin/wp cron event run --due-now > /dev/null 2>&1 && curl -fsS -m 10 --retry 3 -o /dev/null https://steadrun.ru/ping/ВАШ-UUID
В Steadrun создайте проверку типа «Cron» с выражением */5 * * * * и grace-периодом в несколько минут.
Если WP-Cron перестанет запускаться или завершится с ошибкой, придёт алерт в Telegram или на почту.
Подробнее в быстром старте. Бесплатно можно следить за пятью задачами.
Что дальше
- Crontab и расписание cron: как устроено cron-выражение.
- Cron не отрабатывает: если системный cron не запускает задачу.