Esecuzione di WP Cron su più siti nel modo giusto


18

Ho WordPress Multisite con diversi siti. Ho creato DISABLE_WP_CRONa truemia wp-config.php.

Se impostiamo task cron con wget o curl abbiamo una regola di 30 sec per eseguire lo script PHP. È così piccolo per inviare tonnellate di notifiche e-mail e fare altre cose (forse la connessione al server SMTP remoto è lenta, forse è davvero un mucchio enorme di notifiche e-mail da bbPress o altro).

Forse possiamo usare qualcosa del genere?

php -q wp-cron.php

Ma esegue cron solo su un sito in Multisito (ogni sito ha le proprie attività cron in diverse tabelle MySQL).

PS Sul forum wpmudev.org ho trovato una strana "soluzione" che usa anche Curl.

Un'altra CLI diwp cron PS WP ha comandi fantastici , ma consente solo di eseguire le attività cron manualmente (sì, possiamo usare --urlattr). Per esempio:

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

Hai dato un'occhiata al WP-CLIcodice principale?
Kaiser

Sì. Scorro subito il codice sorgente e cerco di capire :) Il comando per eseguire tutte le attività (eventi) non esiste, forse posso crearlo in futuro.
Kolya Korobochkin,

Hai wp/ WP-CLI nel tuo PATH? Se sì, perché non attivarlo da un file bash in esecuzione in cron?
Kaiser

Sembra fantastico! Ma come eseguire tutte le attività cron da wp cli? Non vedo alcun comando per questo.
Kolya Korobochkin,

Esattamente come hai mostrato alla fine della tua domanda?
Kaiser

Risposte:


13

Penso che il modo migliore sia usare WP-CLI ma per farlo dovresti scrivere uno script bash. Eccone uno che dovrebbe farlo per te:

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

Dovresti quindi aggiungere questo script a crontab ed eseguirlo forse ogni minuto se vuoi


Hm, grazie per la tua opinione, ma penso che questa sia una soluzione confusa (sporca). Penso che sarà meglio scrivere un componente aggiuntivo PHP per wpcli che esegua solo tutte le attività necessarie. Ho bisogno di più tempo per capire le funzioni e il codice WP per farlo.
Kolya Korobochkin,

4
@KolyaKorobochkin Non sono d'accordo. Questo non è per niente indifferente poiché la CLI di WP è stata creata per essere utilizzata dalla riga di comando e negli script bash.
DiverseAndRemote.com il

1
wp cron event run --due-now --url="$SITE_URL" --path="$WP_PATH- Secondo i rundocumenti, è necessario utilizzare la --due-nowbandiera. Ciò ridurrebbe le ricerche e le chiamate ai singoli eventi. Vedi: wp-cli.org/commands/cron/event/run . Ad ogni modo, sono con @OmarJackman - sta usando la riga di comando per usare gli strumenti della riga di comando di WordPress. Puntelli per un chiaro esempio di Bash. È possibile completare questa risposta mostrando la voce crontab.
jgraup,

A beneficio dei futuri lettori, la sceneggiatura avrà quindi il seguente aspetto: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
perplessità

10

Dopo aver aggiunto la costante in wp-config.php

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

WP-CLI

E supponendo che tu abbia config.ymlconfigurato correttamente, puoi ommettere il --pathflag quando chiami cron run.


wp cron event run --due-now

[<hook>…] Uno o più ganci da eseguire.

[--due-now] Esegui subito tutti gli hook previsti.

[--all] Esegui tutti i ganci.


Per eseguire tutte le attività cron dovute in ordine:

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;

Se vuoi che vengano eseguiti contemporaneamente (eseguendo prima il cron non specifico del sito):

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;

Vorresti mettere entrambe le opzioni in un file eseguibile

chmod +x run_all_wp_cron_events_due_now.sh

aggiungere un'attività crontab

crontab -e

e probabilmente eseguire ogni minuto

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

Se si desidera eseguire un comando personalizzato da cron, potrebbe essere necessario specificare i percorsi completi per far funzionare 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

L'unico motivo per cui dovresti caricare WordPress qui è raccogliere gli URL dal database anziché utilizzare un elenco predefinito. Faremo solo il ping di quegli URL e non ci interessa davvero quale sia la risposta.

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

E aggiungi una sola chiamata al tuo custom-cron.phpin un crontab

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

1

One-liner più semplice con meno bash:

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

Puoi eseguirlo manualmente o inserirlo in uno script e chiamarlo da cron come nelle altre risposte.


0

Questa è la mia soluzione:

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

Lo chiamiamo da crontab, spero che aiuti


-5

Penso che devi dirci cosa intendi per "esegui wp-cron.php nel modo giusto" prima di tutto. Secondo Wordpress, non ha senso disabilitare wp-cron e tuttavia si desidera che funzioni ... Dal punto di vista di Linux, wget-ing o / bin / php-ing wp-cron.php sarebbe corretto, ma sembra che il tuo host particolare stia limitando il numero di invocazioni php per motivi di sicurezza? - quella parte non è completamente chiara dalla tua descrizione.

Un'altra domanda: quante e-mail sono "una tonnellata"? Ci sono ottimi motivi per cui non dovresti provare a inviare troppe email così velocemente.

Potrebbe essere necessario ripensare i tuoi obiettivi.

(Vorrei commentare invece di rispondere ma non ho abbastanza reputazione su wpstack.)


3
Esistono diversi modi per eseguire il cron di WordPress. Il meccanismo integrato è attivato dalle visualizzazioni di pagina ed è pratica comune impostare DISABLE_WP_CRONdisabilitare questo metodo quando si configura invece il metodo cron di sistema più affidabile.
Marcus Downing,

La domanda non è perché farlo / se i motivi sono significativi ma come chiamare correttamente wp-cron.php su un'installazione multisito. Abbastanza chiaro per me;)
Philipp

1
Spero che ti renda conto che stai commentando una risposta molto vecchia e già nascosta.
Jorge Orpinel,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.