Executando o WP Cron em vários sites da maneira certa

18

Eu tenho o WordPress Multisite com vários sites. Criei DISABLE_WP_CRONa truena minha wp-config.php.

Se configurarmos a tarefa cron com wget ou curl, teremos uma regra de 30 segundos para executar o script PHP. É muito pequeno enviar toneladas de notificações por email e fazer outras coisas (talvez a conexão remota do servidor SMTP seja lenta, talvez seja realmente um monte enorme de notificações por email do bbPress ou algo assim).

Talvez possamos usar algo assim?

php -q wp-cron.php

Mas é executado apenas cron em um site no Multisite (cada site tem suas próprias tarefas cron em diferentes tabelas MySQL).

PS No fórum wpmudev.org , encontrei uma "solução" estranha que também usa o Curl.

Outra CLI dowp cron PS WP possui comandos impressionantes, mas só permite executar tarefas cron manualmente (sim, podemos usar --urlattr). Por exemplo:

wp cron event list --url=multisite.com
wp cron event list --url=subdomain.multisite.com
Kolya Korobochkin
fonte
Você deu uma olhada no WP-CLIcódigo principal?
Kaiser #
Sim. Eu cavo o código fonte agora e tentando entender :) O comando para executar todas as tarefas (eventos) não existe, talvez eu possa criá-lo no futuro.
Kolya Korobochkin #
Você tem wp/ WP-CLI no seu PATH? Se sim, por que não acionar isso de um arquivo bash em execução no cron?
kaiser
Parece bom! Mas como executar todas as tarefas cron do wp cli? Não vejo nenhum comando para isso.
Kolya Korobochkin
Exatamente como você mostrou no final da sua pergunta?
Kaiser

Respostas:

13

Eu acho que a melhor maneira é usar o WP-CLI, mas você precisará escrever um script bash para fazer isso. Aqui está um que deve fazer isso por você:

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

Você precisará adicionar esse script ao crontab e executá-lo a cada minuto, se quiser

DiverseAndRemote.com
fonte
Hm, obrigado pela sua opinião, mas acho que esta é uma solução hacky (suja). Eu acho que será melhor escrever algum addon PHP para wpcli que apenas execute todas as tarefas necessárias. Preciso de mais tempo para entender as funções e o código do WP.
Kolya Korobochkin 31/01
4
@KolyaKorobochkin Eu discordo. Isso não é hacky desde que o WP CLI foi criado para ser usado na linha de comando e nos scripts do bash.
DiverseAndRemote.com #
11
wp cron event run --due-now --url="$SITE_URL" --path="$WP_PATH- De acordo com os rundocumentos, você deve utilizar a --due-nowbandeira. Isso reduziria as pesquisas e chamadas de eventos individuais. Veja: wp-cli.org/commands/cron/event/run . De qualquer forma, estou com o @OmarJackman - ele está utilizando a linha de comando para usar as ferramentas de linha de comando do WordPress. Adereços para um exemplo limpo do Bash. Você pode completar esta resposta mostrando a entrada crontab.
precisa saber é o seguinte
Para o benefício de futuros leitores, o script se parece com: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
perplexidade
10

Depois de adicionar a constante em wp-config.php

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

WP-CLI

E supondo que você tenha config.ymlconfigurado corretamente, você pode omitir o --pathsinalizador ao ligar cron run.


wp cron event run --due-now

[<hook>…] Um ou mais ganchos para executar.

[--due-now] Execute todos os ganchos devidos agora.

[--all] Execute todos os ganchos.


Para executar todas as tarefas cron devidas em ordem:

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 você deseja que eles sejam executados simultaneamente (executando primeiro o cron não específico do site):

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;

Você gostaria de colocar qualquer opção em um arquivo executável

chmod +x run_all_wp_cron_events_due_now.sh

adicionar uma tarefa crontab

crontab -e

e provavelmente executar cada minuto

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

Se você deseja executar um comando customizado a partir do cron, pode ser necessário especificar os caminhos completos para o wp-cli funcionar.

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

PHP

O único motivo para você carregar o WordPress aqui é reunir os URLs do banco de dados, em vez de usar uma lista predefinida. Vamos apenas executar ping nos URLs e não nos importamos com a resposta.

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 adicione uma única chamada ao seu custom-cron.phpem um crontab

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

Uma linha mais fácil com menos bash:

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

Você pode executá-lo manualmente ou colocá-lo em um script e chamá-lo de cron como nas outras respostas.

Anastis
fonte
0

Esta é a minha solução:

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

Chamamos isso de crontab, espero que ajude

Amon-Ra
fonte
-5

Eu acho que você precisa nos dizer o que você quer dizer com "execute o wp-cron.php da maneira certa" em primeiro lugar. De acordo com o Wordpress, não faz sentido desabilitar o wp-cron e ainda assim executar ... Da perspectiva do Linux, wget-ing ou / bin / php-wp-cron.php estariam corretos, mas parece que seu host em particular está limitando seu número de invocações de php por motivos de segurança? - essa parte não está completamente clara em sua descrição.

Outra pergunta: quantos e-mails são "uma tonelada"? Há ótimas razões pelas quais você não deve tentar enviar muitos emails tão rapidamente.

Você pode ter que repensar seus objetivos.

(Gostaria de comentar em vez de responder, mas não tenho reputação suficiente no wpstack.)

Jorge Orpinel
fonte
3
Existem várias maneiras de executar o cron do WordPress. O mecanismo interno é acionado pelas visualizações de página, e é prática comum definir DISABLE_WP_CRONpara desativar esse método ao configurar o método cron do sistema mais confiável.
Marcus Downing
A questão não é por que fazê-lo / se os motivos são significativos, mas como chamar corretamente o wp-cron.php em uma instalação multisite. Bastante claro para mim;)
Philipp
11
Espero que você perceba que está comentando uma resposta muito antiga e já oculta.
Jorge Orpinel