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

3 нояб. 2014 г., 02:35:41
Просмотры: 15.4K
Голосов: 32

У меня есть мультисайтовая сеть WordPress с несколькими сайтами. Я установил DISABLE_WP_CRON в значение true в файле wp-config.php.

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

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

php -q wp-cron.php

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

P.S. На форуме wpmudev.org я нашел странное "решение", которое также использует Curl.

Еще P.S. WP CLI имеет отличные команды wp cron, но они позволяют запускать cron-задачи только вручную (да, мы можем использовать атрибут --url). Например:

wp cron event list --url=multisite.com
wp cron event list --url=subdomain.multisite.com
7
Комментарии

Вы смотрели исходный код WP-CLI?

kaiser kaiser
3 нояб. 2014 г. 03:36:32

Да. Я как раз изучаю исходный код и пытаюсь разобраться :) Команды для запуска всех задач (событий) не существует, возможно, я смогу её добавить в будущем.

Kolya Korobochkin Kolya Korobochkin
4 нояб. 2014 г. 15:27:42

У вас есть wp/WP-CLI в вашем PATH? Если да, почему бы не запускать его через bash-файл из cron?

kaiser kaiser
4 нояб. 2014 г. 15:38:31

Звучит отлично! Но как запустить все задачи cron через wp cli? Я не вижу команд для этого.

Kolya Korobochkin Kolya Korobochkin
15 нояб. 2014 г. 16:45:07

Точно так же, как вы показали в конце своего вопроса?

kaiser kaiser
16 нояб. 2014 г. 14:38:17

wp cron event list только показывает список запланированных событий. Я не вижу команд для запуска задач. А http://wp-cli.org/commands/cron/event/run/ требует хук (аргумент).

Kolya Korobochkin Kolya Korobochkin
17 нояб. 2014 г. 16:07:24

Стоит упомянуть, что если у вас всего несколько сайтов в мультисайтовой сети без планов по расширению, вы можете просто запускать их по отдельности с помощью wp cron event run --due-now --url=mysite1.com && wp cron event run --due-now --url=mysite2.com и т.д. ... но если вы планируете часто добавлять новые сайты, я считаю, что ответ от @Anastis работает лучше всего.

squarecandy squarecandy
17 апр. 2021 г. 06:49:51
Показать остальные 2 комментариев
Все ответы на вопрос 6
0
20

После того как вы добавили константу в 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;

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

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

// Загрузка WP
require_once( dirname( __FILE__ ) . '/wp-load.php' );

// Проверка версии
global $wp_version;
$gt_4_6 = version_compare( $wp_version, '4.6.0', '>=' );

// Получение блогов
$args  = array( 'archived' => 0, 'deleted' => 0, 'public' => 1 );
$blogs = $gt_4_6 ? get_sites( $args ) : @wp_get_sites( $args ); // >= 4.6

// Запуск Cron для каждого блога
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
14 сент. 2016 г. 19:54:09
5
18

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

WP_PATH="/путь/к/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 и запускать его, например, каждую минуту, если нужно.

28 янв. 2015 г. 07:36:03
Комментарии

Хм, спасибо за ваше мнение, но я считаю это грязным решением. Думаю, будет лучше написать PHP-аддон для wpcli, который просто выполнит все необходимые задачи. Мне нужно больше времени, чтобы разобраться в функциях и коде WordPress для этого.

Kolya Korobochkin Kolya Korobochkin
31 янв. 2015 г. 16:15:05

@KolyaKorobochkin Я не согласен. Это совсем не грязное решение, поскольку WP CLI был создан для использования в командной строке и bash-скриптах.

DiverseAndRemote.com DiverseAndRemote.com
3 дек. 2015 г. 20:15:07

wp cron event run --due-now --url="$SITE_URL" --path="$WP_PATH - Согласно документации run, следует использовать флаг --due-now. Это сократит количество проверок и отдельных вызовов событий. Смотрите: http://wp-cli.org/commands/cron/event/run/. В любом случае, я согласен с @OmarJackman - он использует командную строку для работы с инструментами командной строки WordPress. Отличный пример чистого Bash-кода. Можно дополнить этот ответ, показав запись в crontab.

jgraup jgraup
14 сент. 2016 г. 19:18:19

Для удобства будущих читателей, скрипт выглядит следующим образом: 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

puzzlement puzzlement
16 апр. 2017 г. 03:44:21

Несколько блоггеров за эти годы скопировали этот ответ без указания авторства, это один из самых ранних сниппетов, которые я видел, так что респект!

Jesse Nickles Jesse Nickles
28 мар. 2024 г. 12:38:49
4
13

Более простое однострочное решение с меньшим количеством команд bash:

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

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

7 окт. 2019 г. 15:24:55
Комментарии

Именно то, что я искал - работает так, как заявлено, спасибо!

kero kero
15 окт. 2020 г. 14:19:41

Это гораздо более разумное использование доступных инструментов в WP CLI, чем ответы, в которых прилагают массу усилий для разбора результатов вывода в CSV. Отлично работает!

squarecandy squarecandy
17 апр. 2021 г. 06:45:50

Это самый умный ответ. И его можно напрямую добавить в ваш crontab.

Edd Edd
31 янв. 2024 г. 13:13:17

Очень умно! Теперь мы используем это в SlickStack для Multisite, когда пользователи выбирают метод wpcli для управления их WP-Cron: https://github.com/littlebizzy/slickstack/blob/master/crons/01-cron-minutely.txt

Jesse Nickles Jesse Nickles
28 мар. 2024 г. 13:04:46
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;  // заменяем на основной хост
  }

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

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

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

17 апр. 2018 г. 17:20:48
2

Вы можете найти полное руководство здесь о том, как правильно настроить задание cron для системы WordPress Multisite, чтобы оно запускалось на всех подсайтах и выполняло задания cron. https://support.shorturl.gg/business-marketing-and-seo-forums/topic/you-are-using-wp-cron-incorrectly-in-wordpress-multisite/

Использование стандартного задания cron для отдельных сайтов WordPress работает не очень хорошо, так как стандартное задание WP cron будет запускать задания cron только для основного сайта, и, как следствие, задания cron не будут выполняться на подсайтах.

13 окт. 2022 г. 01:56:29
Комментарии

Хотя данная ссылка может ответить на вопрос, лучше включить основные части ответа здесь и предоставить ссылку для справки. Ответы, состоящие только из ссылок, могут стать недействительными, если страница по ссылке изменится. - Из обзора

cjbj cjbj
14 окт. 2022 г. 10:22:18

Понял. Просто так было проще дать ссылку. Спасибо.

user1554402 user1554402
14 окт. 2022 г. 14:47:15
3
-6

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

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

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

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

13 апр. 2015 г. 23:53:05
Комментарии

Существует несколько способов запуска WordPress cron. Встроенный механизм активируется при посещении страниц, и общепринятой практикой является установка DISABLE_WP_CRON для отключения этого метода при настройке более надежного системного cron.

Marcus Downing Marcus Downing
11 июл. 2016 г. 17:28:36

Вопрос не в том, почему это нужно делать/имеют ли причины смысл, а в том, как правильно вызывать wp-cron.php в мультисайтовой установке. Для меня всё вполне понятно ;)

Philipp Philipp
26 окт. 2017 г. 23:26:56

Надеюсь, вы понимаете, что комментируете очень старый и уже скрытый ответ.

Jorge Orpinel Pérez Jorge Orpinel Pérez
28 окт. 2017 г. 00:03:45