WP Cron auf mehreren Sites richtig ausführen

18

Ich habe WordPress Multisite mit mehreren Websites. Ich setze DISABLE_WP_CRONauf truein meinem wp-config.php.

Wenn wir eine Cron-Task mit wget oder curl einrichten, haben wir eine 30-Sekunden-Regel, um PHP-Skripte auszuführen. Es ist so klein, Unmengen von E-Mail-Benachrichtigungen zu senden und andere Aufgaben zu erledigen (möglicherweise ist die SMTP-Remoteserververbindung langsam, möglicherweise sind es wirklich viele E-Mail-Benachrichtigungen von bbPress oder so).

Vielleicht können wir so etwas verwenden?

php -q wp-cron.php

In Multisite wird jedoch nur cron für eine Site ausgeführt (jede Site hat ihre eigenen cron-Tasks in verschiedenen MySQL-Tabellen).

PS Auf wpmudev.org Forum fand ich seltsame "Lösung", die auch Curl verwenden.

Eine andere PS WP CLI hat tolle wp cronBefehle , erlaubt aber nur das manuelle Ausführen von Cron-Tasks (yep, wir können --urlattr verwenden). Beispielsweise:

wp cron event list --url=multisite.com
wp cron event list --url=subdomain.multisite.com
Kolya Korobochkin
quelle
Haben Sie sich den WP-CLIKerncode angesehen?
Kaiser
Ja. Ich beschäftige mich gerade mit dem Quellcode und versuche zu verstehen :) Der Befehl zum Ausführen aller Aufgaben (Ereignisse) ist nicht vorhanden. Vielleicht kann ich ihn in Zukunft erstellen.
Kolya Korobochkin
Haben Sie wp/ WP-CLI in Ihrem PATH? Wenn ja, warum nicht aus einer Bash-Datei auslösen, die in Cron ausgeführt wird?
Kaiser
Klingt gut! Aber wie kann man alle Cron-Tasks von wp cli ausführen? Ich sehe keine Befehle dafür.
Kolya Korobochkin
Genau so, wie Sie es am Ende Ihrer Frage gezeigt haben?
Kaiser

Antworten:

13

Ich denke, der beste Weg ist, WP-CLI zu verwenden, aber Sie müssten ein Bash-Skript schreiben, um dies zu tun. Hier ist eine, die es für Sie tun sollte:

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

Sie müssten dieses Skript dann zu crontab hinzufügen und es möglicherweise jede Minute ausführen, wenn Sie möchten

DiverseAndRemote.com
quelle
Hm, danke für deine Meinung, aber ich denke, das ist eine abgedroschene Lösung. Ich denke, es wird besser sein, ein PHP-Addon für wpcli zu schreiben, das alle benötigten Aufgaben ausführt. Ich brauche mehr Zeit, um WP-Funktionen und Code zu verstehen.
Kolya Korobochkin
4
@KolyaKorobochkin Ich bin anderer Meinung. Dies ist überhaupt nicht hacky, da WP CLI für die Verwendung in der Befehlszeile und in Bash-Skripten gemacht wurde.
DiverseAndRemote.com
1
wp cron event run --due-now --url="$SITE_URL" --path="$WP_PATH- Laut runDokumentation sollten Sie das --due-nowFlag verwenden. Dies würde die Suche und die einzelnen Ereignisaufrufe verringern. Siehe: wp-cli.org/commands/cron/event/run . Auf jeden Fall arbeite ich mit @OmarJackman - er nutzt die Befehlszeile, um WordPress-Befehlszeilentools zu verwenden. Requisiten für ein sauberes Bash-Beispiel. Sie können diese Antwort abrunden, indem Sie den Eintrag crontab anzeigen.
JGRAUP
Für zukünftige Leser sieht das Skript dann so aus: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
Verwirrung
10

Nachdem Sie die Konstante hinzugefügt haben wp-config.php

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

WP-CLI

Und vorausgesetzt, Sie haben Ihr config.ymlSetup korrekt, können Sie das --pathFlag beim Aufruf weglassen cron run.


wp cron event run --due-now

[<hook>…] Ein oder mehrere Hooks, die ausgeführt werden sollen.

[--due-now] Führen Sie jetzt alle fälligen Hooks aus.

[--all] Führen Sie alle Haken aus.


So führen Sie alle fälligen Cron-Tasks in der angegebenen Reihenfolge aus:

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;

Wenn Sie möchten, dass sie gleichzeitig ausgeführt werden (zuerst das nicht standortspezifische Cron ausführen):

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;

Sie möchten eine der beiden Optionen in eine ausführbare Datei einfügen

chmod +x run_all_wp_cron_events_due_now.sh

Fügen Sie eine Crontab-Aufgabe hinzu

crontab -e

und wahrscheinlich jede Minute ausführen

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

Wenn Sie einen benutzerdefinierten Befehl von cron ausführen möchten , müssen Sie möglicherweise die vollständigen Pfade angeben, damit wp-cli funktioniert.

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

PHP

Der einzige Grund, warum Sie WordPress hier laden müssen, ist, die URLs aus der Datenbank zu sammeln, anstatt eine vordefinierte Liste zu verwenden. Wir werden nur diese URLs pingen und es ist uns egal, wie die Antwort lautet.

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

Und fügen Sie einen einzelnen Anruf custom-cron.phpin einer Crontab hinzu

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

Einfacherer Einzeiler mit weniger Druck:

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

Sie können es entweder manuell ausführen oder in ein Skript einfügen und wie in den anderen Antworten von cron aus aufrufen.

Anastis
quelle
0

Das ist meine Lösung:

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

Wir nennen das crontab, hoffe es hilft

Amon-Ra
quelle
-5

Ich denke, Sie müssen uns in erster Linie sagen, was Sie unter "wp-cron.php richtig ausführen" verstehen. Laut Wordpress macht es keinen Sinn, dass Sie wp-cron deaktivieren und dennoch ausführen möchten ... Aus Linux-Sicht wäre wget-ing oder / bin / php-ing wp-cron.php richtig, aber es scheint, dass Ihr spezieller Host Ihre Anzahl von PHP-Aufrufen aus Sicherheitsgründen begrenzt? - Dieser Teil ergibt sich nicht ganz aus Ihrer Beschreibung.

Eine andere Frage: Wie viele E-Mails sind "eine Tonne"? Es gibt gute Gründe, warum Sie nicht versuchen sollten, so schnell zu viele E-Mails zu senden.

Möglicherweise müssen Sie Ihre Ziele überdenken.

(Ich würde kommentieren, anstatt zu antworten, aber ich habe nicht genug Reputation auf wpstack.)

Jorge Orpinel
quelle
3
Es gibt mehrere Möglichkeiten, den WordPress-Cron auszuführen. Der integrierte Mechanismus wird durch Seitenaufrufe ausgelöst. Es ist üblich DISABLE_WP_CRON, diese Methode zu deaktivieren, wenn Sie stattdessen die zuverlässigere System-Cron-Methode einrichten.
Marcus Downing
Die Frage ist nicht, warum das so ist / ob die Gründe sinnvoll sind, sondern wie man wp-cron.php bei einer Installation mit mehreren Standorten korrekt aufruft. Für mich ganz klar;)
Philipp
1
Ich hoffe, Sie bemerken, dass Sie eine sehr alte und bereits verborgene Antwort kommentieren.
Jorge Orpinel