После того, как запланированные посты в WordPress не опубликовались вовремя, были исследованы логи сервера и было замечено, что при обращении к файлу wp-cron.php состояние HTTP ответов было не 200, как положено, а 499:
"POST /wp-cron.php?doing_wp_cron HTTP/1.0" 499
На сервере используется связка Apache + Nginx. Как оказалось, Nginx не перенаправлял запрос на Apache, если соединение было закрыто слишком быстро — раньше, чем сервер успел прочесть заголовки.
Как следствие планировщик не запускался и различные задачи не выполнялись.
Ситуацию можно исправить, отредактировав файл wp-includes/cron.php.
Было:
function spawn_cron( $local_time = 0 ) { ... wp_remote_post( $cron_url, array('timeout' => 0.01, 'blocking' => false, 'sslverify' => apply_filters('https_local_ssl_verify', true)) );
Стало:
function spawn_cron( $local_time = 0 ) { ... wp_remote_post( $cron_url, array('timeout' => 5, 'blocking' => false, 'sslverify' => apply_filters('https_local_ssl_verify', true)) ); usleep(5000000); //5 sec wait for nginx
Изменили время «timeout» до 5 секунд и поставили задержку 5 секунд с помощью функции usleep.
Дополнительный материал: