Uruchamianie WP Cron na wielu serwerach we właściwy sposób


18

Mam WordPress Multisite z kilkoma stronami. Założyłem DISABLE_WP_CRONsię truew moim wp-config.php.

Jeśli skonfigurujemy zadanie crona za pomocą wget lub curl, mamy 30 sekundową regułę do wykonania skryptu PHP. Wysyłanie mnóstwa powiadomień e-mail i robienie innych rzeczy jest tak małe (może zdalne połączenie z serwerem SMTP jest powolne, może naprawdę duża wiązka powiadomień e-mail z bbPress lub cokolwiek innego).

Może możemy użyć czegoś takiego?

php -q wp-cron.php

Ale uruchamia on crona tylko na jednej stronie w Multisite (każda strona ma swoje własne zadania cron w różnych tabelach MySQL).

PS Na forum wpmudev.org znalazłem dziwne „rozwiązanie”, które również używa Curl.

Kolejny PS WP CLI ma niesamowite wp cronpolecenia, ale pozwala tylko na ręczne uruchamianie zadań cron (tak, możemy użyć --urlattr). Na przykład:

wp cron event list --url=multisite.com
wp cron event list --url=subdomain.multisite.com

Czy spojrzałeś na WP-CLIkod podstawowy?
kaiser

Tak. Wkopuję teraz kod źródłowy i próbuję zrozumieć :) Polecenie uruchomienia wszystkich zadań (zdarzeń) nie istnieje, być może uda mi się go utworzyć w przyszłości.
Kolya Korobochkin

Czy masz wp/ WP-CLI w swoim PATH? Jeśli tak, dlaczego nie uruchomić tego z pliku bash uruchomionego w cronie?
kaiser

Brzmi wspaniale! Ale jak uruchomić wszystkie zadania cron z wp cli? Nie widzę w tym żadnych poleceń.
Kolya Korobochkin

Dokładnie tak, jak pokazałeś na końcu swojego pytania?
kaiser

Odpowiedzi:


13

Myślę, że najlepszym sposobem jest użycie WP-CLI, ale aby to zrobić, musisz napisać skrypt bash. Oto taki, który powinien to dla Ciebie zrobić:

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

Musisz wtedy dodać ten skrypt do crontab i uruchomić go może co minutę, jeśli chcesz


Hm, dziękuję za twoją opinię, ale myślę, że to hacky (brudny) sposób. Myślę, że lepiej będzie napisać jakiś dodatek PHP dla wpcli, który po prostu uruchamia wszystkie potrzebne zadania. Potrzebuję więcej czasu, aby zrozumieć funkcje WP i kod, aby to zrobić.
Kolya Korobochkin

4
@KolyaKorobochkin Nie zgadzam się. Nie jest to wcale hacking, ponieważ WP CLI został stworzony do użycia w linii poleceń i skryptach bash.
DiverseAndRemote.com

1
wp cron event run --due-now --url="$SITE_URL" --path="$WP_PATH- Według rundokumentów powinieneś użyć --due-nowflagi. Zmniejszyłoby to liczbę wyszukiwań i indywidualnych wywołań zdarzeń. Zobacz: wp-cli.org/commands/cron/event/run . Tak czy inaczej, jestem z @OmarJackman - używa wiersza poleceń do korzystania z narzędzi wiersza poleceń WordPress. Rekwizyty dla czystego przykładu Bash. Możesz zaokrąglić tę odpowiedź, pokazując wpis crontab.
jgraup

Z korzyścią dla przyszłych czytelników skrypt wygląda następująco: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
zagadka

10

Po dodaniu stałej w wp-config.php

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

WP-CLI

Zakładając, że config.ymlkonfiguracja jest prawidłowa, możesz pominąć --pathflagę podczas połączenia cron run.


wp cron event run --due-now

[<hook>…] Jeden lub więcej haczyków do uruchomienia.

[--due-now] Uruchom teraz wszystkie haki.

[--all] Uruchom wszystkie haki.


Aby uruchomić wszystkie zadania CRON w kolejności:

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;

Jeśli chcesz, aby działały równolegle (najpierw uruchamiając cron inny niż lokacja):

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;

Chcesz umieścić dowolną opcję w pliku wykonywalnym

chmod +x run_all_wp_cron_events_due_now.sh

dodaj zadanie crontab

crontab -e

i prawdopodobnie wykonują co minutę

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

Jeśli chcesz uruchomić niestandardowe polecenie z crona, może być konieczne określenie pełnych ścieżek działania 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

Jedynym powodem, dla którego musisz załadować WordPress tutaj, jest zebranie adresów URL z bazy danych zamiast korzystania ze wstępnie zdefiniowanej listy. Będziemy pingować tylko te adresy URL i nie obchodzi nas, jaka jest odpowiedź.

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 );
}

I dodaj jedno połączenie do twojego custom-cron.phpw crontab

* * * * * wget -q -O - http://your-site.com/custom-cron.php?doing_wp_cron

1

Łatwiejszy jednowarstwowy z mniejszym uderzeniem:

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

Możesz uruchomić go ręcznie lub umieścić w skrypcie i wywołać z crona, jak w innych odpowiedziach.


0

To jest moje rozwiązanie:

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();

Nazywamy to od crontab, mam nadzieję, że to pomoże


-5

Myślę, że musisz przede wszystkim powiedzieć, co rozumiesz przez „uruchom wp-cron.php we właściwy sposób”. Według Wordpress nie ma sensu wyłączanie wp-cron, a mimo to chcesz, aby działało ... Z punktu widzenia Linuksa, wget-ing lub / bin / php-ing wp-cron.php byłoby poprawne, ale wygląda na to, że twój konkretny host ogranicza twoją liczbę wywołań php ze względów bezpieczeństwa? - ta część nie jest całkowicie jednoznaczna z twojego opisu.

Kolejne pytanie: ile e-maili to „tona”? Są świetne powody, dla których nie powinieneś próbować zbyt szybko wysyłać zbyt wielu wiadomości e-mail.

Być może będziesz musiał przemyśleć swoje cele.

(Chciałbym skomentować zamiast odpowiadać, ale nie mam wystarczającej reputacji na wpstack.)


3
Istnieje wiele sposobów uruchamiania crona WordPress. Wbudowany mechanizm jest uruchamiany przez odsłony stron i powszechną praktyką DISABLE_WP_CRONjest wyłączanie tej metody podczas ustawiania bardziej niezawodnej metody cron systemu.
Marcus Downing

Pytanie nie brzmi, dlaczego to zrobić / jeśli przyczyny są znaczące, ale jak poprawnie wywołać wp-cron.php w instalacji na wielu serwerach. Dla mnie całkiem jasne;)
Filip

1
Mam nadzieję, że zdajesz sobie sprawę, że komentujesz bardzo starą i już ukrytą odpowiedź.
Jorge Orpinel
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.