Правильный запуск WP Cron на мультисайтах

18

У меня WordPress Multisite с несколькими сайтами. Я настроен DISABLE_WP_CRONна trueмой wp-config.php.

Если мы настроим задачу cron с помощью wget или curl, у нас будет правило 30 секунд для выполнения PHP-скрипта. Это так мало, чтобы отправлять тонны уведомлений по электронной почте и делать другие вещи (возможно, подключение к удаленному SMTP-серверу медленное, может быть, это действительно огромная куча уведомлений по электронной почте от bbPress или чего-то еще).

Может быть, мы можем использовать что-то вроде этого?

php -q wp-cron.php

Но он запускает cron только для одного сайта в Multisite (каждый сайт имеет свои собственные задачи cron в разных таблицах MySQL).

PS На форуме wpmudev.org я нашел странное «решение», в котором также используется Curl.

Другой PS WP CLI имеет отличные wp cronкоманды, но он позволяет запускать задачи cron только вручную (да, мы можем использовать --urlattr). Например:

wp cron event list --url=multisite.com
wp cron event list --url=subdomain.multisite.com
Коля Коробочкин
источник
Вы взглянули на WP-CLIосновной код?
Кайзер
Да. Я копаюсь в исходном коде прямо сейчас и пытаюсь понять :) Команды для запуска всех задач (событий) не существует, возможно я смогу ее создать в будущем.
Коля Коробочкин
Есть ли у вас wp/ WP-CLI в вашем PATH? Если да, почему бы не вызвать это из bash-файла, запущенного в cron?
Кайзер
Звучит здорово! Но как запустить все задачи cron из wp cli? Я не вижу никаких команд для этого.
Коля Коробочкин
Точно так же, как вы показали в конце вашего вопроса?
Кайзер

Ответы:

13

Я думаю, что лучший способ - это использовать WP-CLI, но для этого вам нужно написать скрипт bash. Вот тот, который должен сделать это для вас:

WP_PATH="/path/to/wp"
for SITE_URL in = $(wp site list --fields=domain,path,archived,deleted --format=csv --path="$WP_PATH" | grep ",0,0$" | awk -F ',' '{print $1 $2}')
do
    for EVENT_HOOK in $(wp cron event list --format=csv --fields=hook,next_run_relative --url="$SITE_URL" --path="$WP_PATH" | grep \"now\"$ | awk -F ',' '{print $1}')
    do
        wp cron event run "$EVENT_HOOK" --url="$SITE_URL" --path="$WP_PATH"
    done
done

Затем вам нужно добавить этот скрипт в crontab и запускать его каждую минуту, если хотите

DiverseAndRemote.com
источник
Хм, спасибо за ваше мнение, но я думаю, что это хакерское (грязное) решение. Я думаю, что будет лучше написать PHP-аддон для wpcli, который просто запускает все необходимые задачи. Мне нужно больше времени, чтобы понять функции WP и код для этого.
Коля Коробочкин
4
@KolyaKorobochkin Я не согласен. Это совсем не хакерство, поскольку WP CLI был создан для использования в командной строке и в скриптах bash.
DiverseAndRemote.com
1
wp cron event run --due-now --url="$SITE_URL" --path="$WP_PATH- Согласно runдокументам, вы должны использовать --due-nowфлаг. Это уменьшит количество поисков и отдельных событий. Смотрите: wp-cli.org/commands/cron/event/run . В любом случае, я с @OmarJackman - он использует командную строку для использования инструментов командной строки WordPress. Реквизит для чистого примера Bash. Вы можете завершить этот ответ, показав запись в crontab.
jgraup
Для удобства читателей в будущем, сценарий , то выглядит следующим образом :WP_PATH="/path/to/wp"; for SITE_URL in $(wp site list --fields=domain,path,archived,deleted --format=csv --path="$WP_PATH" | grep ",0,0$" | awk -F ',' '{print $1 $2}'); do wp cron event run --due-now --url="$SITE_URL" --path="$WP_PATH"; done
недоуменно
10

После того, как вы добавили константу в wp-config.php

defined('DISABLE_WP_CRON') or define('DISABLE_WP_CRON', true);

WP-CLI

И при условии, что у вас config.ymlправильно настроены настройки, вы можете опустить --pathфлаг при вызове cron run.


wp cron event run --due-now

[<hook>…] Один или несколько крючков для запуска.

[--due-now] Запустите все крюки из-за прямо сейчас.

[--all] Запустите все крючки.


Чтобы выполнить все задачи cron по порядку:

function run_crons_due_now_in_order { for SITE_URL in $(wp site list --fields=url --format=csv | tail -n +2 | sort); do wp cron event run --due-now --url="$SITE_URL" && echo -e "\t+ Finished crons for $SITE_URL"; done; echo "Done"; }; run_crons_due_now_in_order;

Если вы хотите, чтобы они запускались одновременно (сначала запустите cron, не зависящий от сайта):

function run_all_crons_due_now { for SITE_URL in $(wp site list --fields=url --format=csv | tail -n +2 | sort); do wp cron event run --due-now --url="$SITE_URL" && echo -e "\t+ Finished crons for $SITE_URL" & done; wait $(jobs -p); echo "Done"; }; run_all_crons_due_now;

Вы хотели бы поместить любой вариант в исполняемый файл

chmod +x run_all_wp_cron_events_due_now.sh

добавить задачу crontab

crontab -e

и, вероятно, выполнить каждую минуту

* * * * * run_all_wp_cron_events_due_now.sh > /dev/null

Если вы хотите запустить пользовательскую команду из cron, вам может потребоваться указать полные пути для работы wp-cli .

* * * * * cd /home/username/public_html; /usr/local/bin/php /home/username/wp-cli.phar your-custom-cron-commands run >/dev/null 2>&1

PHP

Единственная причина, по которой вам нужно загрузить WordPress, - это собирать URL-адреса из базы данных, а не использовать заранее определенный список. Мы собираемся пинговать только те URL-адреса, и нам все равно, какой ответ.

custom-cron.php

<?php

// Load WP
require_once( dirname( __FILE__ ) . '/wp-load.php' );

// Check Version
global $wp_version;
$gt_4_6 = version_compare( $wp_version, '4.6.0', '>=' );

// Get Blogs
$args  = array( 'archived' => 0, 'deleted' => 0, 'public' => 1 );
$blogs = $gt_4_6 ? get_sites( $args ) : @wp_get_sites( $args ); // >= 4.6

// Run Cron on each blog
echo "Running Crons: " . PHP_EOL;
$agent = 'WordPress/' . $wp_version . '; ' . home_url();
$time  = time();

foreach ( $blogs as $blog ) {
    $domain  = $gt_4_6 ? $blog->domain : $blog['domain'];
    $path    = $gt_4_6 ? $blog->path : $blog['path'];
    $command = "http://" . $domain . ( $path ? $path : '/' ) . 'wp-cron.php?doing_wp_cron=' . $time . '&ver=' . $wp_version;

    $ch = curl_init( $command );
    $rc = curl_setopt( $ch, CURLOPT_RETURNTRANSFER, false );
    $rc = curl_exec( $ch );
    curl_close( $ch );

    print_r( $rc );
    print_r( "\t✔ " . $command . PHP_EOL );
}

И добавить один звонок к вашему custom-cron.phpв crontab

* * * * * wget -q -O - http://your-site.com/custom-cron.php?doing_wp_cron
jgraup
источник
1

Проще один вкладыш с меньшим количеством ошибок:

wp site list --field=url | xargs -i -n1 wp cron event run --due-now --url="{}"

Вы можете запустить его вручную или поместить в скрипт и вызвать его из cron, как и в других ответах.

Anastis
источник
0

Это мое решение:

global $multisite_hosts;
$multisite_hosts = Array('xxxx.dev.xxx.oondeo.es','x2.dev.xxx.oondeo.es','x3.dev.xxx.oondeo.es');

function run_cron(){
  global $multisite_hosts;
  $host=array_pop($multisite_hosts);
  if (!$host)
    return;
  register_shutdown_function('shutdown');
  if (!isset($_SERVER['HTTP_HOST'])) {
       $_SERVER['HTTP_HOST'] = $host;  // replace with primary host
  }

  require './wp-cron.php';
}

function shutdown()
{
  run_cron();
}
run_cron();

Мы называем это из crontab, надеюсь, это поможет

Амон-Ра
источник
-5

Я думаю, что вы должны сказать нам, что вы подразумеваете под "запустить wp-cron.php правильный путь" в первую очередь. Согласно Wordpress, нет смысла отключать wp-cron и все же хотеть, чтобы он работал ... С точки зрения Linux, wget-ing или / bin / php-ing wp-cron.php будет правильным, но кажется, ваш конкретный хост ограничивает количество вызовов php по соображениям безопасности? - эта часть не совсем понятна из вашего описания.

Другой вопрос: сколько писем "тонна"? Есть веские причины, почему вы не должны пытаться отправить слишком много писем так быстро.

Возможно, вам придется пересмотреть свои цели.

(Я бы прокомментировал вместо ответа, но у меня недостаточно репутации на wpstack.)

Хорхе Орпинель
источник
3
Есть несколько способов запуска cron WordPress. Встроенный механизм запускается просмотром страниц, и обычно рекомендуется DISABLE_WP_CRONотключать этот метод при настройке более надежного системного метода cron.
Маркус Даунинг
Вопрос не в том, зачем это делать / если причины имеют смысл, а в том, как правильно вызвать wp-cron.php в многосайтовой установке. Совершенно ясно для меня;)
Филипп
1
Я надеюсь, вы понимаете, что комментируете очень старый и уже скрытый ответ.
Хорхе Орпинель