1. Paquetes
  2. Laravel Horizon

Introducción

Nota Antes de adentrarse en Laravel Horizon, debería familiarizarse con los servicios de cola base de Laravel. Horizon complementa la cola de Laravel con características adicionales que pueden resultar confusas si no está familiarizado con las funciones básicas de la cola ofrecidas por Laravel.

Laravel Horizon proporciona un hermoso panel de control y configuración basada en código para las colas de Redis de Laravel. Horizon le permite supervisar fácilmente métricas clave de su sistema de colas, como el rendimiento de trabajos, el tiempo de ejecución y los fallos de trabajos.

Cuando utiliza Horizon, toda la configuración del trabajador de su cola se almacena en un solo y simple archivo de configuración. Al definir la configuración del trabajador de su aplicación en un archivo controlado por versiones, puede escalar o modificar fácilmente los trabajadores de la cola de su aplicación al implementarla.

Instalación

Advertencia Laravel Horizon requiere que utilice Redis para alimentar su cola. Por lo tanto, asegúrese de que su conexión a la cola esté configurada como redis en el archivo de configuración config/queue.php de su aplicación.

Puede instalar Horizon en su proyecto utilizando el administrador de paquetes Composer:

composer require laravel/horizon

Después de instalar Horizon, publique sus activos con el comando Artisan horizon:install:

php artisan horizon:install

Configuración

Después de publicar los activos de Horizon, su archivo de configuración principal estará ubicado en config/horizon.php. Este archivo de configuración le permite configurar las opciones del trabajador de la cola para su aplicación. Cada opción de configuración incluye una descripción de su propósito, así que asegúrese de explorar a fondo este archivo.

Advertencia Horizon utiliza una conexión Redis llamada horizon internamente. Este nombre de conexión Redis está reservado y no debe asignarse a otra conexión Redis en el archivo de configuración database.php o como el valor de la opción use en el archivo de configuración horizon.php.

Entornos

Después de la instalación, la opción principal de configuración de Horizon con la que debería familiarizarse es la opción de configuración environments. Esta opción de configuración es una matriz de entornos en los que se ejecuta su aplicación y define las opciones de los procesos de trabajo para cada entorno. Por defecto, esta entrada contiene un entorno production y local. Sin embargo, puede agregar más entornos según sea necesario:

'environments' => [
'production' => [
'supervisor-1' => [
'maxProcesses' => 10,
'balanceMaxShift' => 1,
'balanceCooldown' => 3,
],
],
 
'local' => [
'supervisor-1' => [
'maxProcesses' => 3,
],
],
],

Cuando inicie Horizon, utilizará las opciones de configuración de los procesos de trabajo para el entorno en el que se está ejecutando su aplicación. Típicamente, el entorno se determina por el valor de la variable de entorno APP_ENV. Por ejemplo, el entorno predeterminado de Horizon, local, está configurado para iniciar tres procesos de trabajo y equilibrar automáticamente la cantidad de procesos de trabajo asignados a cada cola. El entorno predeterminado production está configurado para iniciar un máximo de 10 procesos de trabajo y equilibrar automáticamente la cantidad de procesos de trabajo asignados a cada cola.

Advertencia Asegúrese de que la sección environments de su archivo de configuración horizon contenga una entrada para cada entorno en el que planea ejecutar Horizon.

Supervisores

Como puede ver en el archivo de configuración predeterminado de Horizon, cada entorno puede contener uno o más "supervisores". Por defecto, el archivo de configuración define este supervisor como supervisor-1; sin embargo, es libre de nombrar a sus supervisores como desee. Cada supervisor es esencialmente responsable de "supervisar" un grupo de procesos de trabajo y se encarga de equilibrar los procesos de trabajo en las colas.

Puede agregar supervisores adicionales a un entorno dado si desea definir un nuevo grupo de procesos de trabajo que debe ejecutarse en ese entorno. Puede optar por hacer esto si desea definir una estrategia de equilibrio o un recuento de procesos de trabajo diferentes para una cola específica utilizada por su aplicación.

Valores Predeterminados

Dentro del archivo de configuración predeterminado de Horizon, notará una opción de configuración defaults. Esta opción de configuración especifica los valores predeterminados para los supervisores de su aplicación. Los valores de configuración predeterminados del supervisor se fusionarán en la configuración del supervisor para cada entorno, lo que le permitirá evitar repeticiones innecesarias al definir sus supervisores.

Estrategias de Balanceo

A diferencia del sistema de cola predeterminado de Laravel, Horizon le permite elegir entre tres estrategias de equilibrio de trabajadores: simple, auto y false. La estrategia simple divide equitativamente los trabajos entrantes entre los procesos de trabajo:

'balance' => 'simple',

La estrategia auto, que es la configuración predeterminada del archivo de configuración, ajusta el número de procesos de trabajo por cola según la carga actual de la cola. Por ejemplo, si su cola de notifications tiene 1,000 trabajos pendientes mientras que su cola de render está vacía, Horizon asignará más trabajadores a su cola de notifications hasta que la cola esté vacía.

Al usar la estrategia auto, puede definir las opciones de configuración minProcesses y maxProcesses para controlar el número mínimo y máximo de procesos de trabajo que Horizon debe escalar hacia arriba y hacia abajo:

'environments' => [
'production' => [
'supervisor-1' => [
'connection' => 'redis',
'queue' => ['default'],
'balance' => 'auto',
'autoScalingStrategy' => 'time',
'minProcesses' => 1,
'maxProcesses' => 10,
'balanceMaxShift' => 1,
'balanceCooldown' => 3,
'tries' => 3,
],
],
],

El valor de configuración autoScalingStrategy determina si Horizon asignará más procesos de trabajo a colas según el tiempo total que llevará limpiar la cola (estrategia time) o por el número total de trabajos en la cola (estrategia size).

Los valores de configuración balanceMaxShift y balanceCooldown determinan qué tan rápido Horizon escalará para satisfacer la demanda de trabajadores. En el ejemplo anterior, se creará o destruirá como máximo un nuevo proceso cada tres segundos. Puede ajustar libremente estos valores según las necesidades de su aplicación.

Cuando la opción balance está establecida en false, se usará el comportamiento predeterminado de Laravel, donde las colas se procesan en el orden en que están listadas en su archivo de configuración.

Autorización del Panel de Control

Horizon expone un panel de control en la URI /horizon. Por defecto, solo podrá acceder a este panel en el entorno local. Sin embargo, dentro de su archivo app/Providers/HorizonServiceProvider.php, hay una definición de puerta de autorización. Esta puerta de autorización controla el acceso a Horizon en entornos no locales. Puede modificar esta puerta según sea necesario para restringir el acceso a su instalación de Horizon:

/**
* Registrar la puerta de Horizon.
*
* Esta puerta determina quién puede acceder a Horizon en entornos no locales.
*/
protected function gate(): void
{
Gate::define('viewHorizon', function (User $user) {
return in_array($user->email, [
]);
});
}

Estrategias de Autenticación Alternativas

Recuerde que Laravel inyecta automáticamente al usuario autenticado en el cierre de la puerta. Si su aplicación proporciona seguridad para Horizon a través de otro método, como restricciones de IP, entonces los usuarios de Horizon pueden no necesitar "iniciar sesión". Por lo tanto, deberá cambiar la firma de cierre function (User $user) anterior a function (User $user = null) para forzar a Laravel a no requerir autenticación.

Trabajos Silenciados

A veces, es posible que no le interese ver ciertos trabajos enviados por su aplicación o paquetes de terceros. En lugar de que estos trabajos ocupen espacio en su lista de "Trabajos Completados", puede silenciarlos. Para comenzar, agregue el nombre de la clase del trabajo a la opción de configuración silenced en el archivo de configuración horizon de su aplicación:

'silenced' => [
App\Jobs\ProcessPodcast::class,
],

Alternativamente, el trabajo que desea silenciar puede implementar la interfaz Laravel\Horizon\Contracts\Silenced. Si un trabajo implementa esta interfaz, se silenciará automáticamente, incluso si no está presente en la matriz de configuración silenced:

use Laravel\Horizon\Contracts\Silenced;
 
class ProcessPodcast implements ShouldQueue, Silenced
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
 
// ...
}

Actualización de Horizon

Al actualizar a una nueva versión principal de Horizon, es importante que revise cuidadosamente la guía de actualización. Además, al actualizar a cualquier nueva versión de Horizon, debería republicar los activos de Horizon:

php artisan horizon:publish

Para mantener los activos actualizados y evitar problemas en futuras actualizaciones, puede agregar el comando vendor:publish --tag=laravel-assets a los scripts post-update-cmd en el archivo composer.json de su aplicación:

{
"scripts": {
"post-update-cmd": [
"@php artisan vendor:publish --tag=laravel-assets --ansi --force"
]
}
}

Ejecutando Horizon

Una vez que haya configurado sus supervisores y trabajadores en el archivo de configuración config/horizon.php de su aplicación, puede iniciar Horizon usando el comando Artisan horizon. Este único comando iniciará todos los procesos de trabajo configurados para el entorno actual:

php artisan horizon

Puede pausar el proceso de Horizon e instruirlo a continuar procesando trabajos usando los comandos Artisan horizon:pause y horizon:continue:

php artisan horizon:pause
 
php artisan horizon:continue

También puede pausar y continuar supervisores específicos de Horizon supervisores usando los comandos Artisan horizon:pause-supervisor y horizon:continue-supervisor:

php artisan horizon:pause-supervisor supervisor-1
 
php artisan horizon:continue-supervisor supervisor-1

Puede verificar el estado actual del proceso de Horizon usando el comando Artisan horizon:status:

php artisan horizon:status

Puede terminar el proceso de Horizon de manera controlada usando el comando Artisan horizon:terminate. Cualquier trabajo que se esté procesando actualmente se completará y luego Horizon dejará de ejecutarse:

php artisan horizon:terminate

Implementando Horizon

Cuando esté listo para implementar Horizon en el servidor real de su aplicación, debe configurar un monitor de procesos para supervisar el comando php artisan horizon y reiniciarlo si se cierra inesperadamente. No se preocupe, discutiremos cómo instalar un monitor de procesos a continuación.

Durante el proceso de implementación de su aplicación, debe indicar al proceso de Horizon que se detenga para que se reinicie mediante su monitor de procesos y reciba sus cambios de código:

php artisan horizon:terminate

Instalación de Supervisor

Supervisor es un monitor de procesos para el sistema operativo Linux y reiniciará automáticamente su proceso horizon si deja de ejecutarse. Para instalar Supervisor en Ubuntu, puede usar el siguiente comando. Si no está utilizando Ubuntu, es probable que pueda instalar Supervisor mediante el administrador de paquetes de su sistema operativo:

sudo apt-get install supervisor

Nota Si configurar Supervisor por su cuenta le resulta abrumador, considere usar Laravel Forge, que instalará y configurará automáticamente Supervisor para sus proyectos de Laravel.

Configuración de Supervisor

Los archivos de configuración de Supervisor se almacenan típicamente en el directorio /etc/supervisor/conf.d de su servidor. Dentro de este directorio, puede crear cualquier cantidad de archivos de configuración que indiquen a Supervisor cómo se deben supervisar sus procesos. Por ejemplo, creemos un archivo horizon.conf que inicie y supervise un proceso horizon:

[program:horizon]
process_name=%(program_name)s
command=php /home/forge/example.com/artisan horizon
autostart=true
autorestart=true
user=forge
redirect_stderr=true
stdout_logfile=/home/forge/example.com/horizon.log
stopwaitsecs=3600

Al definir su configuración de Supervisor, asegúrese de que el valor de stopwaitsecs sea mayor que la cantidad de segundos consumidos por su trabajo de mayor duración. De lo contrario, Supervisor puede finalizar el trabajo antes de que termine de procesarse.

Advertencia Si bien los ejemplos anteriores son válidos para servidores basados en Ubuntu, la ubicación y la extensión del archivo de configuración de Supervisor pueden variar entre otros sistemas operativos de servidor. Consulte la documentación de su servidor para obtener más información.

Iniciando Supervisor

Una vez que se haya creado el archivo de configuración, puede actualizar la configuración de Supervisor e iniciar los procesos supervisados con los siguientes comandos:

sudo supervisorctl reread
 
sudo supervisorctl update
 
sudo supervisorctl start horizon

Nota Para obtener más información sobre cómo ejecutar Supervisor, consulte la documentación de Supervisor.

Etiquetas

Horizon le permite asignar "etiquetas" a trabajos, incluyendo correos electrónicos, eventos de difusión, notificaciones y escuchadores de eventos en cola. De hecho, Horizon etiquetará de manera inteligente y automática la mayoría de los trabajos según los modelos Eloquent que estén vinculados al trabajo. Por ejemplo, eche un vistazo al siguiente trabajo:

<?php
 
namespace App\Jobs;
 
use App\Models\Video;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
 
class RenderVideo implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
 
/**
* Crear una nueva instancia de trabajo.
*/
public function __construct(
public Video $video,
) {}
 
/**
* Ejecutar el trabajo.
*/
public function handle(): void
{
// ...
}
}

Si este trabajo se encola con una instancia de App\Models\Video que tiene un atributo id de 1, recibirá automáticamente la etiqueta App\Models\Video:1. Esto se debe a que Horizon buscará en las propiedades del trabajo cualquier modelo Eloquent. Si se encuentran modelos Eloquent, Horizon etiquetará inteligentemente el trabajo usando el nombre de clase y la clave primaria del modelo:

use App\Jobs\RenderVideo;
use App\Models\Video;
 
$video = Video::find(1);
 
RenderVideo::dispatch($video);

Etiquetado Manual de Trabajos

Si desea definir manualmente las etiquetas para uno de sus objetos en cola, puede definir un método tags en la clase:

class RenderVideo implements ShouldQueue
{
/**
* Obtener las etiquetas que se deben asignar al trabajo.
*
* @return array<int, string>
*/
public function tags(): array
{
return ['render', 'video:'.$this->video->id];
}
}

Notificaciones

Advertencia Cuando configure Horizon para enviar notificaciones de Slack o SMS, debe revisar los prerrequisitos para el canal de notificación relevante.

Si desea recibir notificaciones cuando una de sus colas tenga un tiempo de espera largo, puede utilizar los métodos Horizon::routeMailNotificationsTo, Horizon::routeSlackNotificationsTo y Horizon::routeSmsNotificationsTo. Puede llamar a estos métodos desde el método boot del proveedor de servicios de Horizon de su aplicación App\Providers\HorizonServiceProvider:

/**
* Inicializar los servicios de la aplicación.
*/
public function boot(): void
{
parent::boot();
 
Horizon::routeSmsNotificationsTo('15556667777');
Horizon::routeMailNotificationsTo('[email protected]');
Horizon::routeSlackNotificationsTo('slack-webhook-url', '#channel');
}

Configuración de Umbrales de Tiempo de Espera de Notificación

Puede configurar cuántos segundos se consideran una "espera larga" en el archivo de configuración config/horizon.php de su aplicación. La opción de configuración waits en este archivo le permite controlar el umbral de espera largo para cada combinación de conexión/cola. Cualquier combinación de conexión/cola no definida se establecerá por defecto en un umbral de espera largo de 60 segundos:

'waits' => [
'redis:critical' => 30,
'redis:default' => 60,
'redis:batch' => 120,
],

Métricas

Horizon incluye un panel de control de métricas que proporciona información sobre los tiempos de espera y el rendimiento de trabajos y colas. Para poblar este panel, debe configurar el comando Artisan snapshot de Horizon para que se ejecute cada cinco minutos a través del programador de su aplicación:

/**
* Definir el cronograma de comandos de la aplicación.
*/
protected function schedule(Schedule $schedule): void
{
$schedule->command('horizon:snapshot')->everyFiveMinutes();
}

Eliminando Trabajos Fallidos

Si desea eliminar un trabajo fallido, puede usar el comando horizon:forget. El comando horizon:forget acepta el ID o UUID del trabajo fallido como su único argumento:

php artisan horizon:forget 5

Limpiando Trabajos de Colas

Si desea eliminar todos los trabajos de la cola predeterminada de su aplicación, puede hacerlo usando el comando Artisan horizon:clear:

php artisan horizon:clear

Puede proporcionar la opción queue para eliminar trabajos de una cola específica:

php artisan horizon:clear --queue=emails