Cómo ejecutar WP-Cron correctamente en redes Multisite de WordPress

3 nov 2014, 02:35:41
Vistas: 15.4K
Votos: 32

Tengo una instalación de WordPress Multisite con varios sitios. He configurado DISABLE_WP_CRON como true en mi archivo wp-config.php.

Si configuramos una tarea cron con wget o curl, tenemos una limitación de 30 segundos para ejecutar el script PHP. Este tiempo es insuficiente para enviar grandes cantidades de notificaciones por correo y realizar otras tareas (quizás la conexión con el servidor SMTP remoto es lenta, o hay una gran cantidad de notificaciones de bbPress).

¿Podríamos usar algo como esto?

php -q wp-cron.php

Pero esto solo ejecuta el cron para un sitio en Multisite (cada sitio tiene sus propias tareas cron en diferentes tablas de MySQL).

P.D.: En el foro de wpmudev.org encontré una "solución" extraña que también usa Curl.

Otra P.D.: WP CLI tiene comandos excelentes para wp cron pero solo permite ejecutar tareas cron manualmente (sí, podemos usar el atributo --url). Por ejemplo:

wp cron event list --url=multisite.com
wp cron event list --url=subdominio.multisite.com
7
Comentarios

¿Has echado un vistazo al código principal de WP-CLI?

kaiser kaiser
3 nov 2014 03:36:32

Sí. Estoy revisando el código fuente ahora mismo y tratando de entenderlo :) El comando para ejecutar todas las tareas (eventos) no existe, tal vez pueda crearlo en el futuro.

Kolya Korobochkin Kolya Korobochkin
4 nov 2014 15:27:42

¿Tienes wp/WP-CLI en tu PATH? Si es así, ¿por qué no activarlo desde un archivo bash que se ejecute en cron?

kaiser kaiser
4 nov 2014 15:38:31

¡Suena genial! Pero, ¿cómo ejecutar todas las tareas cron desde wp cli? No veo ningún comando para esto.

Kolya Korobochkin Kolya Korobochkin
15 nov 2014 16:45:07

¿Exactamente como has mostrado al final de tu pregunta?

kaiser kaiser
16 nov 2014 14:38:17

wp cron event list solo muestra la lista de eventos programados. No veo ningún comando para ejecutar tareas. Y http://wp-cli.org/commands/cron/event/run/ necesita un hook (argumento).

Kolya Korobochkin Kolya Korobochkin
17 nov 2014 16:07:24

Vale la pena mencionar que si solo tienes unos pocos sitios en tu red multisite sin planes de crecimiento, siempre podrías ejecutarlos individualmente con wp cron event run --due-now --url=misitio1.com && wp cron event run --due-now --url=misitio2.com etc. ... pero si planeas agregar sitios con frecuencia, creo que la respuesta de @Anastis funciona mejor.

squarecandy squarecandy
17 abr 2021 06:49:51
Mostrar los 2 comentarios restantes
Todas las respuestas a la pregunta 6
0
20

Después de haber agregado la constante en wp-config.php

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

WP-CLI

Asumiendo que tienes tu archivo config.yml configurado correctamente, puedes omitir el flag --path al llamar a cron run.


wp cron event run --due-now

[<hook>…] Uno o más hooks para ejecutar.

[--due-now] Ejecutar todos los hooks que estén pendientes ahora.

[--all] Ejecutar todos los hooks.


Para ejecutar todas las tareas cron pendientes en orden:

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;

Si prefieres ejecutarlas concurrentemente (ejecutando primero el cron no específico del sitio):

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;

Deberías guardar cualquiera de las opciones en un archivo ejecutable

chmod +x run_all_wp_cron_events_due_now.sh

agregar una tarea al crontab

crontab -e

y probablemente ejecutarla cada minuto

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

Si necesitas ejecutar un comando personalizado desde cron, quizás debas especificar las rutas completas para que wp-cli funcione.

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

PHP

La única razón por la que necesitarías cargar WordPress aquí es para obtener las URLs desde la base de datos en lugar de usar una lista predefinida. Solo vamos a hacer ping a esas URLs y no nos importa realmente la respuesta.

custom-cron.php

<?php

// Cargar WordPress
require_once( dirname( __FILE__ ) . '/wp-load.php' );

// Verificar versión
global $wp_version;
$gt_4_6 = version_compare( $wp_version, '4.6.0', '>=' );

// Obtener blogs
$args  = array( 'archived' => 0, 'deleted' => 0, 'public' => 1 );
$blogs = $gt_4_6 ? get_sites( $args ) : @wp_get_sites( $args ); // >= 4.6

// Ejecutar Cron en cada blog
echo "Ejecutando 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 );
}

Y agregar una única llamada a tu archivo custom-cron.php en el crontab

* * * * * wget -q -O - http://your-site.com/custom-cron.php?doing_wp_cron
14 sept 2016 19:54:09
5
18

Creo que la mejor manera es usar WP-CLI pero necesitarías escribir un script bash para hacer esto. Aquí tienes uno que debería funcionar:

WP_PATH="/ruta/hacia/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

Luego necesitarías agregar este script al crontab y ejecutarlo quizás cada minuto si lo deseas

28 ene 2015 07:36:03
Comentarios

Hm, gracias por tu opinión pero creo que esta es una solución un poco sucia (hacky). Creo que sería mejor escribir algún complemento PHP para wpcli que ejecute todas las tareas necesarias. Necesito más tiempo para entender las funciones y el código de WP para hacerlo.

Kolya Korobochkin Kolya Korobochkin
31 ene 2015 16:15:05

@KolyaKorobochkin No estoy de acuerdo. Esto no es nada sucio ya que WP CLI fue hecho para usarse en la línea de comandos y en scripts bash.

DiverseAndRemote.com DiverseAndRemote.com
3 dic 2015 20:15:07

wp cron event run --due-now --url="$SITE_URL" --path="$WP_PATH - Según la documentación de run, deberías utilizar el flag --due-now. Esto reduciría las búsquedas y llamadas individuales a eventos. Ver: http://wp-cli.org/commands/cron/event/run/. De cualquier manera, estoy con @OmarJackman - está utilizando la línea de comandos para usar herramientas de WordPress en línea de comandos. Felicitaciones por un ejemplo limpio de Bash. Podrías complementar esta respuesta mostrando la entrada en el crontab.

jgraup jgraup
14 sept 2016 19:18:19

Para beneficio de los lectores futuros, el script entonces luce así: 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

puzzlement puzzlement
16 abr 2017 03:44:21

Varios blogueros parecen haber plagiado esta respuesta a lo largo de los años sin darte crédito, es uno de los fragmentos más antiguos que he visto, ¡felicitaciones!

Jesse Nickles Jesse Nickles
28 mar 2024 12:38:49
4
13

Formato más sencillo de una sola línea con menos comandos bash:

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

Puedes ejecutarlo manualmente o incluirlo en un script y llamarlo desde cron como en las otras respuestas.

7 oct 2019 15:24:55
Comentarios

Exactamente lo que estaba buscando - funciona tal como se anuncia, ¡gracias!

kero kero
15 oct 2020 14:19:41

Este es un uso mucho más inteligente de las herramientas disponibles en WP CLI que las respuestas que hacen un gran esfuerzo para separar los resultados de la salida CSV. ¡Funciona genial!

squarecandy squarecandy
17 abr 2021 06:45:50

Esta es la respuesta más inteligente. Y puedes poner esto directamente en tu crontab.

Edd Edd
31 ene 2024 13:13:17

¡Muy inteligente! Estamos usando esto en SlickStack para Multisite ahora, cuando los usuarios seleccionan el método wpcli para administrar su WP-Cron: https://github.com/littlebizzy/slickstack/blob/master/crons/01-cron-minutely.txt

Jesse Nickles Jesse Nickles
28 mar 2024 13:04:46
0

Esta es mi solución:

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;  // reemplazar con el host principal
  }

  require './wp-cron.php';
}

function shutdown()
{
  run_cron();
}
run_cron();

Llamamos a esto desde crontab, espero que ayude

17 abr 2018 17:20:48
2

Puedes encontrar una guía completa aquí sobre cómo configurar correctamente el trabajo cron para un sistema WordPress Multisite, de modo que se ejecute en todos los sub-sitios y active los trabajos cron. https://support.shorturl.gg/business-marketing-and-seo-forums/topic/you-are-using-wp-cron-incorrectly-in-wordpress-multisite/

Usar el trabajo cron estándar para sitios web WordPress independientes no funciona bien, ya que el trabajo cron estándar de WP solo activará el cron para el sitio principal y, por lo tanto, no se ejecutarán trabajos cron en los sub-sitios.

13 oct 2022 01:56:29
Comentarios

Aunque este enlace puede responder a la pregunta, es mejor incluir aquí las partes esenciales de la respuesta y proporcionar el enlace como referencia. Las respuestas que solo contienen enlaces pueden volverse inválidas si la página enlazada cambia. - De la revisión

cjbj cjbj
14 oct 2022 10:22:18

Entiendo. Simplemente era más fácil enlazarlo. Gracias.

user1554402 user1554402
14 oct 2022 14:47:15
3
-6

Creo que primero debes explicarnos a qué te refieres con "ejecutar wp-cron.php de la manera correcta". Según WordPress, no tiene sentido que deshabilites wp-cron y aún así quieras que se ejecute... Desde la perspectiva de Linux, usar wget o /bin/php en wp-cron.php sería lo correcto, pero parece que tu host en particular está limitando el número de invocaciones de PHP por razones de seguridad? -- esa parte no queda completamente clara en tu descripción.

Otra pregunta: ¿a cuántos emails te refieres con "un montón"? Hay buenas razones por las que no deberías intentar enviar demasiados emails tan rápidamente.

Puede que tengas que reconsiderar tus objetivos.

(Comentaría en lugar de responder, pero no tengo suficiente reputación en wpstack.)

13 abr 2015 23:53:05
Comentarios

Existen múltiples formas de ejecutar el cron de WordPress. El mecanismo incorporado se activa mediante visitas a la página, y es una práctica común establecer DISABLE_WP_CRON para deshabilitar este método cuando se configura el método más confiable de cron del sistema en su lugar.

Marcus Downing Marcus Downing
11 jul 2016 17:28:36

La pregunta no es por qué hacerlo/si las razones son significativas, sino cómo llamar correctamente a wp-cron.php en una instalación multisitio. Bastante claro para mí ;)

Philipp Philipp
26 oct 2017 23:26:56

Espero que te des cuenta de que estás comentando una respuesta muy antigua y ya oculta.

Jorge Orpinel Pérez Jorge Orpinel Pérez
28 oct 2017 00:03:45