Cada vez que un usuario carta una página de tu WordPress, éste hace una llamada a un archivo, el wp-cron.php, que se encarga de comprobar si hay tareas programadas que deban realizarse, como publicar entradas programadas, realizar copias de seguridad o ver si hay actualizaciones disponibles.
Es una buena solución ya que WordPress debe estar preparado para funcionar de forma independiente al servidor en el que esté, pero es tremendamente ineficiente: a poco que tengas unos cientos de visitas en tu web, el cron de WordPress comenzará a suponer una carga apreciable para la CPU de tu servidor.
Así que vamos a ver cómo mejorar este sistema suprimiendo el cron de WordPress y estableciendo un cron real, de forma que tu web consuma muchos menos recursos del servidor.
Tabla de contenidos
Qué es un cron
Los sistemas operativos (específicamente los de tipo UNIX o UNIX-like, que es el que usan la mayoría de servidores en internet) incluyen un proceso que está permanentemente ejecutándose en segundo plano (los informáticos damos a este tipo de procesos el sugerente nombre de «demonios») que ejecuta tareas de forma regular.
Este demonio se llama cron, y es lo que permite programar tareas. Descargar los emails, comprobar si hay actualizaciones, lanzar un análisis del antivirus, recordarnos una entrada del calendario… Cualquier tarea que deba realizarse en el futuro por un programa, de forma puntual o recurrente, es administrada y ejecutada por el cron.
El cron de WordPress
WordPress también necesita ejecutar tareas programadas. Las estás utilizando cuando:
- Programas un post para que se publique a un día y una hora
- Estableces una rutina de copias de seguridad automáticas
- WordPress comprueba si hay actualizaciones del core, de los temas o de los plugins que tienes instalados
- Se envían los pingbacks o se comprueba si hay trackbacks
- Actualizas de forma regular el catálogo de productos de tu ecommerce mediante la descarga automática de un CSV de tu proveedor
En fin, como decía, cualquier tarea que deba realizarse en un futuro, de forma puntual o periódica. Sin embargo para WordPress no es tan sencillo establecer un cron: debe asegurarse que funciona correctamente en cualquier servidor que en el que se instale, sea cual sea su sistema operativo, versión, software instalado…
El archivo wp-cron.php
WordPress soluciona esto de una forma ingeniosa: cada vez que un visitante de la web carga una página, es llamado el archivo wp-cron.php, que es el que realiza la tarea del cron.
Como solución es ingeniosa, sí, pero puede no ser eficaz o no ser eficiente, dependiendo de la cantidad de visitantes que reciba tu web:
- Si la web recibe pocas visitas, el cron de WordPress no se ejecuta con la suficiente frecuencia, y se pueden perder tareas programadas. Ya hablamos del tema cuando vimos posibles soluciones al problema de la programación perdida en WordPress.
- Si la web comienza a recibir muchas visitas, el proceso se ejecutará demasiado a menudo.
El cron de WordPress y el consumo de CPU del servidor
Demasiado a menudo. Si recibes, digamos, mil visitas diarias (una cifra relativamente discreta) y cada visitante ve de media tres páginas de la web, el cron de WordPress se ejecuta tres mil veces al día, unas dos veces por minuto de media.
Eso es tremendamente ineficiente. No sólo es mucho más de lo necesario (no hace falta comprobar dos veces por minuto si hay tareas pendientes de ejecución, de hecho basta con dos veces por hora) sino que además genera un alto consumo de CPU por parte del servidor.
Y claro, aquí es donde comienzan los problemas: el hosting te limita la web, tienes que cambiar a un plan superior, tu web (y, de paso, todas las que están alojadas en el mismo servidor compartido) se ralentiza…
Como solución genérica al problema del cron, el asunto está bien, pero llegados a este punto no necesitas algo genérico sino algo que se adapte a tu situación. Se impone una solución drástica.
Suprimir el cron de WordPress
Así que el tema pasa por suprimir el cron de WordPress y programar un cron real a través de nuestro servidor. WordPress no puede hacerlo (ya he dicho que tiene que ser compatible con cualquier tipo de servidor) pero nosotros sí.
Y el primer paso es deshabilitar el wp-cron.php, de forma que no sea llamado cada vez que se carga una página. Y hacerlo es muy fácil, sólo tienes que añadir una línea a tu archivo wp-config.php (como siempre, antes de modificar ningún archivo guárdate una copia de seguridad.
Así que accedes al archivo (está en la raíz del servidor, donde están las carpetas wp-admin, wp-content y wp-includes) y lo editas. Sólo tienes que buscar la línea donde dice ¡Eso es todo, deja de editar! Feliz blogging y, justo antes de ella, añadir esta otra:
define ('DISABLE_WP_CRON', true);
Eso es todo, desde este momento WordPress no hará más llamadas al wp-cron.php, y el consumo de CPU del servidor se reducirá apreciablemente. Claro que no podemos quedarnos ahí: seguimos necesitando las tareas programadas. Así que estableceremos una llamada regular al archivo de cron desde el propio servidor.
¿Estás construyendo tu tienda online o eres implementador WordPress?
¿Necesitas plugins de calidad y con soporte para implementar funcionalidades concretas?
Consigue todos los plugins a la venta en la sección de plugins de esta web y todos los que siga añadiendo. Acceso a los 96 plugins (y subiendo) con soporte directo del desarrollador, actualizaciones y uso ilimitado: úsalos en tantas webs como lo necesites.
Establecer un cron real
Si la parte anterior era fácil, tampoco se puede decir que ésta sea complicada. Especialmente porque los servicios de hosting suelen ofrecer una interfaz bastante intuitiva para hacerlo. Es verdad que para ello habrá que utilizar un comando UNIX, pero ésa parte te la voy a dar hecha. 😉
Lo primero que tendrás que hacer es localizar la opción en el panel de control de tu hosting. Seguro que por el nombre (cron, cron jobs, trabajos cron, etc) te será muy sencillo localizarla. Si es un cPanel lo tienes en la sección Avanzada > Cron Trabajos, donde verás algo así:
Establecer la periodicidad del trabajo es sencillo. De hecho, la propia interfaz te lo facilita en el desplegable Configuración común, en el que puedes seleccionar opciones como Una vez por minuto, Dos veces por hora, etcétera. Una periodicidad de una o como mucho dos veces por hora es correcta.
En cuanto al comando, el que debes utilizar es el siguiente:
wget -q -O – -t 1 http://tuweb.com/wp-cron.php?doing_wp_cron >/dev/null 2>&1
Lo que significa:
- wget: sirve para solicitar un archivo remotamente a través del protocolo HTTP, HTTPS o incluso FTP. En este caso el archivo que solicitaremos será el wp-cron.php
- -q (también puedes poner –quiet): esta opción se usa para desactivar la salida del comando y se ejecute de forma «silenciosa», sin mostrar mensajes de salida.
- -O –: registra la salida del comando a la salida estándar. Esta salida estándar, en sistemas UNIX-like, es la pantalla, pero nosotros vamos a derivarla en la última parte del comando.
- -t 1: por defecto, wget intenta recuperar el archivo hasta 20 veces si no lo consigue de primeras, lo cual no es lo más adecuado si lo que queremos es reducir el consumo de CPU. Con -t 1 le decimos que haga un único intento.
- >/dev/null 2>&1: esta opción permite derivar cualquier salida generada por el comando desde la salida estándar al dispositivo /dev/null, que en UNIX, Linux y sistemas similares es una especio de agujero negro que se traga cualquier cosa que va ahí. Un cubo de basura con esteroides. Así además evitamos el correo electrónico que genera cron notificando el resultado de la tarea, puesto que nos hemos deshecho de ese resultado.
Y listo. Con esto acabamos de reducir el número de peticiones al archivo wp-cron.php desde las miles de veces al día de nuestro ejemplo, a sólo una o dos por hora, lo que reducirá sensiblemente el consumo de CPU del servidor. Problema resuelto, y a otra cosa.
Por supuesto, realizar este tipo de tareas está incluido en mi servicio de mantenimiento web y soporte para WordPress.
El wysija_cron de MailPoet
Resulta que has deshabilitado el cron de WordPress en el wp-config.php, pero en tu servidor sigues viendo accesos al archivo wp-cron.php. ¿Qué está pasando aquí?
Si usas MailPoet para gestionar tus boletines electrónicos, ésa puede ser la causa. Resulta que MailPoet incluye su propia rutina cron que, por defecto, está activada. Si estás estableciendo un cron real, deberías desactivar esta opción.
Sólo tienes que ir a MailPoet > Ajustes > Avanzado y mostrar las Opciones de Geek. En ellas verás una que dice Activar las tareas pre-programadas de servidor (cron), que por defecto está activada. Así que ya sabes: tienes que cambiar esa opción a Configuraré una tarea automatizada en mi servidor para ejecutar con la frecuencia que deseo.
Además, ahí mismo te dice qué URL debes llamar desde el cron para ejecutar esa tarea.
Larry dice
Muchas gracias por el tutorial, me ha servido. Saludos.
Enrique J. Ros dice
Me alegra que te haya sido útil, Larry 🙂
Un saludo
Marcos dice
¿Podrías actualizar el artículo a la nueva versión de Mailpoet?
Gracias
Jaime dice
Gracias por el tutorial,
solo tengo una duda, ese procedimiento genera este error en el estado de salud del sitio?
El evento programado, action_scheduler_run_queue, no se ha podido ejecutar. Tu sitio todavía funciona, pero esto puede indicar que las entradas programadas o las actualizaciones automáticas no funcionen como deberían.
Enrique J. Ros dice
Hola Jaime
Dado que el cron está desactivado, te informa de ello.
Un saludo
Jaime dice
Muchas Gracias Enrique
Saludos