Eseguire WP-Cron correttamente su reti Multisite?
Ho un'installazione WordPress Multisite con diversi siti. Ho impostato DISABLE_WP_CRON
a true
nel mio wp-config.php
.
Se configuriamo un task cron con wget o curl abbiamo il limite di 30 secondi per l'esecuzione dello script PHP. È troppo poco per inviare tonnellate di notifiche email e fare altre operazioni (forse il server SMTP remoto è lento, o magari c'è un enorme carico di notifiche email da bbPress o altro).
Forse possiamo usare qualcosa come questo?
php -q wp-cron.php
Ma questo esegue il cron solo per un sito nella rete Multisite (ogni sito ha i propri task cron in diverse tabelle MySQL).
P.S. Nel forum wpmudev.org ho trovato una strana "soluzione" che usa anche Curl.
Altro P.S. WP CLI ha fantastici comandi wp cron
ma permettono solo di eseguire manualmente i task cron (sì, possiamo usare l'attributo --url
). Per esempio:
wp cron event list --url=multisite.com
wp cron event list --url=subdomain.multisite.com
Dopo aver aggiunto la costante in wp-config.php
defined('DISABLE_WP_CRON') or define('DISABLE_WP_CRON', true);
WP-CLI
E assumendo che tu abbia il tuo file config.yml
configurato correttamente, puoi omettere il flag --path
quando chiami cron run
.
wp cron event run --due-now
[<hook>…]
Uno o più hook da eseguire.
[--due-now]
Esegui tutti gli hook scaduti in questo momento.
[--all]
Esegui tutti gli hook.
Per eseguire tutte le attività cron scadute 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 eseguirli in modo concorrente (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;
Vorrai mettere una delle due opzioni in un file eseguibile
chmod +x run_all_wp_cron_events_due_now.sh
aggiungi un'attività crontab
crontab -e
e probabilmente eseguirla ogni minuto
* * * * * run_all_wp_cron_events_due_now.sh > /dev/null
Se vuoi eseguire un comando personalizzato da cron, potresti dover 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 è per raccogliere gli URL dal database piuttosto che usare una lista predefinita. Stiamo solo per pingare quegli URL e non ci interessa realmente quale sia la risposta.
custom-cron.php
<?php
// Carica WP
require_once( dirname( __FILE__ ) . '/wp-load.php' );
// Controlla la versione
global $wp_version;
$gt_4_6 = version_compare( $wp_version, '4.6.0', '>=' );
// Ottieni i blog
$args = array( 'archived' => 0, 'deleted' => 0, 'public' => 1 );
$blogs = $gt_4_6 ? get_sites( $args ) : @wp_get_sites( $args ); // >= 4.6
// Esegui Cron su ogni blog
echo "Esecuzione 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 singola chiamata al tuo custom-cron.php
in un crontab
* * * * * wget -q -O - http://your-site.com/custom-cron.php?doing_wp_cron

Penso che il modo migliore sia usare WP-CLI ma dovresti scrivere uno script bash per farlo. Ecco uno che dovrebbe funzionare per te:
WP_PATH="/percorso/di/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 poi aggiungere questo script a crontab e eseguirlo magari ogni minuto se lo desideri

Hm grazie per la tua opinione ma penso che questa sia una soluzione approssimativa (sporca). Credo sarebbe meglio scrivere qualche addon PHP per wpcli che esegua semplicemente tutte le attività necessarie. Ho bisogno di più tempo per comprendere le funzioni e il codice di WP per farlo.

@KolyaKorobochkin Non sono d'accordo. Non è affatto approssimativo dato che WP CLI è stato creato per essere utilizzato dalla linea di comando e in script bash.

wp cron event run --due-now --url="$SITE_URL" --path="$WP_PATH
- Secondo la documentazione di run
, dovresti utilizzare il flag --due-now
. Questo ridurrebbe i lookup e le chiamate individuali agli eventi. Vedi: http://wp-cli.org/commands/cron/event/run/. In ogni caso, sono d'accordo con @OmarJackman - sta utilizzando la linea di comando per usare gli strumenti da riga di comando di WordPress. Complimenti per un esempio pulito di Bash. Potresti completare questa risposta mostrando l'entry crontab.

Per il beneficio dei lettori futuri, lo script appare quindi così: 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

Esattamente quello che stavo cercando - funziona proprio come descritto, grazie!

Questo è un utilizzo molto più intelligente degli strumenti disponibili in WP CLI rispetto alle risposte che si sforzano di elaborare i risultati dell'output CSV. Funziona alla grande!

Questa è la risposta più intelligente. E puoi inserirla direttamente nel tuo crontab.

Molto intelligente! Lo stiamo utilizzando in SlickStack per Multisite ora, quando gli utenti selezionano il metodo wpcli
per gestire il loro WP-Cron: https://github.com/littlebizzy/slickstack/blob/master/crons/01-cron-minutely.txt

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; // sostituisci con l'host principale
}
require './wp-cron.php';
}
function shutdown()
{
run_cron();
}
run_cron();
Chiamiamo questo script da crontab, spero sia utile

Puoi trovare una guida completa qui su come configurare correttamente il cron job per un sistema WordPress Multisite in modo che venga eseguito su tutti i sottositi e faccia partire i cron job. https://support.shorturl.gg/business-marketing-and-seo-forums/topic/you-are-using-wp-cron-incorrectly-in-wordpress-multisite/
Utilizzare il cron job standard per i siti WordPress standalone non funziona bene perché il cron job WP standard attiverà il cron job solo per il sito principale e di conseguenza nessun cron job verrà eseguito sui sottositi.

Anche se questo link potrebbe rispondere alla domanda, è meglio includere qui le parti essenziali della risposta e fornire il link come riferimento. Le risposte che contengono solo link possono diventare non valide se la pagina collegata cambia. - Da Recensione

Penso che prima di tutto dovresti spiegarci cosa intendi con "eseguire wp-cron.php nel modo giusto". Secondo WordPress, non ha senso disabilitare wp-cron e poi volerlo eseguire... Dal punto di vista Linux, usare wget o /bin/php su wp-cron.php sarebbe corretto, ma sembra che il tuo host specifico stia limitando il numero di invocazioni PHP per ragioni di sicurezza? Questa parte non è del tutto chiara dalla tua descrizione.
Un'altra domanda: quante email sono "un sacco"? Ci sono ottime ragioni per cui non dovresti cercare di inviare troppe email così rapidamente.
Potresti dover ripensare ai tuoi obiettivi.
(Vorrei commentare invece di rispondere, ma non ho abbastanza reputazione su wpstack.)

Esistono diversi modi per eseguire il cron di WordPress. Il meccanismo integrato viene attivato dalle visualizzazioni delle pagine, ed è pratica comune impostare DISABLE_WP_CRON
per disabilitare questo metodo quando si configura invece il più affidabile metodo system cron.

La domanda non è perché farlo/se le ragioni sono valide, ma come chiamare correttamente wp-cron.php in un'installazione multisito. Abbastanza chiaro per me ;)
