Introducción

Horizon proporciona un bonito panel de control y sistema de configuración controlado por código para Laravel, potenciado por colas de Redis. Horizon te permite monitorear fácilmente métricas claves de tu sistema de colas tales como tasa de rendimiento, tiempo de ejecución y fallas de tareas.

Toda la configuración de tu worker es almacenada en un solo archivo de configuración sencillo, permitiendo que tu configuración quede en el código fuente donde tu equipo completo pueda colaborar.

Instalación

Debes asegurarte de que tu conexión de cola está establecido a redis en tu archivo de configuración queue.

Puedes usar Composer para instalar Horizon en tu proyecto de Laravel:

composer require laravel/horizon ~3.0

Después de instalar Horizon, publica sus assets usando el comando Artisan horizon:install:

php artisan horizon:install

Configuración

Después de publicar los assets de Horizon, su principal archivo de configuración será colocado en config/horizon.php. Este archivo de configuración permite que configures las opciones del worker y cada opción de configuración incluye una descripción de su propósito, así que asegúrate de explorar con gran detalle este archivo.

Debes asegurarte de que la porción environments de tu archivo de configuración horizon contiene una entrada para cada entorno en el que planeas ejecutar Horizon.

Opciones de balance

Horizon permite que elijas entre tres estrategias de balance: simple, auto y false. La estrategia simple, que es la opción por defecto del archivo de configuración, divide los trabajos entrantes de manera uniforme entre procesos:

'balance' => 'simple',

La estrategia auto ajusta el número de procesos trabajadores por cola basado en la carga de trabajo de la cola. Por ejemplo, si tu cola notifications tiene 1.000 trabajos esperando mientras tu cola render está vacía, Horizon asignará mas trabajadores a tu cola notifications hasta que esté vacía. Cuando la opción balance esté establecida a false, el comportamiento predeterminado de Laravel será usado, el cual procesa las colas en el orden que son listadas en tu configuración.

Al momento de usar la estrategia auto, puedes definir las opciones de configuración minProcesses y maxProcesses para controlar el número mínimo y máximo de procesos al que Horizon debería expandir o contraer. El valor de minProcesses especifica el número mínimo de procesos por cola, mientras que el valor de maxProcesses especifica el número máximo de procesos a través de todas las colas:

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

Recorte de trabajos

El archivo de configuración de horizon te permite configurar el tiempo que los trabajos recientes y fallidos deben ser persistidos (en minutos). Por defecto, los trabajos recientes son mantenidos por una hora mientras que los trabajos fallidos son mantenidos por una semana:

'trim' => [
    'recent' => 60,
    'failed' => 10080,
],

Autorización del panel de control

Horizon muestra un panel de control en /horizon. Por defecto, sólo serás capaz de acceder a este panel de control en el entorno local. Dentro de tu archivo app/Providers/HorizonServiceProvider.php, hay un método gate. Este gate o compuerta de autorización controla el acceso a Horizon en entornos no locales. Eres libre de modificar este gate como sea necesario para restringir el acceso a tu instalación de Horizon:

/**
* Register the Horizon gate.
*
* This gate determines who can access Horizon in non-local environments.
*
* @return void
*/
protected function gate()
{
    Gate::define('viewHorizon', function ($user) {
        return in_array($user->email, [
            '[email protected]',
        ]);
    });
}

Recuerda que Laravel inyecta el usuario autenticado al Gate de forma automática. Si tu aplicación está proporcionando seguridad de Horizon mediante algún otro método, como restricciones de IP, entonces tus usuarios de Horizon pueden no necesitar iniciar sesión. Por lo tanto, necesitarás cambiar el function ($user) de arriba por function ($user = null) para forzar a Laravel a que no requiera autenticación.

Actualización de Horizon

Al actualizar a una nueva versión mayor de Horizon, es importante que revises cuidadosamente la guía de actualización.

Además, debes volver a publicar los assets de Horizon:

php artisan horizon:assets

Ejecutando Horizon

Una vez que has configurado tus workers en el archivo de configuración config/horizon.php, puedes ejecutar Horizon usando el comando Artisan horizon. Este único comando iniciará todos tus workers configurados:

php artisan horizon

Puedes pausar los procesos de Horizon e instruirlo para continuar procesando trabajos usando los comandos Artisan horizon:pause y horizon:continue:

php artisan horizon:pause

php artisan horizon:continue

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

php artisan horizon:status

Puedes terminar elegantemente el proceso maestro de Horizon en tu máquina usando el comando Artisan horizon:terminate. Cualquiera de los trabajos que Horizon esté procesando actualmente será completado y después Horizon parará:

php artisan horizon:terminate

Hacer deploy de Horizon

Si estás haciendo deploy de Horizon en un servidor activo, deberías configurar un monitor de proceso para monitorear el comando php artisan horizon y reiniciarlo si éste sale inesperadamente. Al momento de usar código reciente en tu servidor, necesitarás instruir el proceso maestro de Horizon para que termine así puede ser reiniciado por tu monitor de proceso y recibir tu cambios de código.

Instalación de Supervisor

Supervisor es un monitor de proceso para el sistema operativo Linux, y reiniciará automáticamente tu proceso horizon si falla. Para instalar Supervisor en Ubuntu, puedes usar el siguiente comando:

sudo apt-get install supervisor

Si el trabajo de configurar Supervisor por ti mismo te parece abrumador, considera el uso de Laravel Forge, que instala y configura automáticamente Supervisor en tus proyectos de Laravel.

Configuración de Supervisor

Los archivos de configuración de Supervisor son guardados típicamente en el directorio /etc/supervisor/conf.d. Dentro de este directorio, puedes crear cualquier número de archivos de configuración que instruyan a Supervisor cómo sus procesos deben ser monitoreados. Por ejemplo, vamos a crear un archivo horizon.conf que inicie y monitoree un proceso horizon:

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

Deberías asequrar que el valor de stopwaitsecs sea mayor que el número de segundos consumidos por la ejecución de tu trabajo más largo. De otra manera, Supervisor cancelará el trabajo antes de que haya finalizado su procesamiento.

Iniciando Supervisor

Una vez que el archivo de configuración haya sido creado, puedes actualizar la configuración de Supervisor e iniciar los procesos usando los siguientes comandos:

sudo supervisorctl reread

sudo supervisorctl update

sudo supervisorctl start horizon

Para mayor información sobre Supervisor, consulta la documentación de Supervisor.

Etiquetas

Horizon permite que asignes «etiquetas» a los trabajos, incluyendo correos utilizando la clase mailable, difusiones de eventos, notificaciones y listeners de eventos en cola. De hecho, Horizon etiquetará inteligente y automáticamente la mayoría de los trabajos dependiendo de los modelos Eloquent que estén adjuntos al trabajo. Por ejemplo, demos un vistazo al siguiente trabajo:

<?php

namespace App\Jobs;

use App\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;

    /**
    * The video instance.
    *
    * @var \App\Video
    */
    public $video;

    /**
    * Create a new job instance.
    *
    * @param  \App\Video  $video
    * @return void
    */
    public function __construct(Video $video)
    {
        $this->video = $video;
    }

    /**
    * Execute the job.
    *
    * @return void
    */
    public function handle()
    {
        //
    }
}

Si este trabajo es encolado con una instancia App\Video que tenga un id de 1, recibirá automáticamente la etiqueta App\Video:1. Esto es debido a que Horizon examinará las propiedades del trabajo para cualquier modelo Eloquent. Si los modelos Eloquent son encontrados, Horizon etiquetará inteligentemente el trabajo usando el nombre de la clase y la clave primaria del modelo:

$video = App\Video::find(1);

App\Jobs\RenderVideo::dispatch($video);

Etiquetado manual

Si prefieres definir manualmente las etiquetas para uno de tus objetos encolables, puedes definir un método tags en la clase:

class RenderVideo implements ShouldQueue
{
    /**
    * Get the tags that should be assigned to the job.
    *
    * @return array
    */
    public function tags()
    {
        return ['render', 'video:'.$this->video->id];
    }
}

Notificaciones

Al momento de configurar Horizon para enviar notificaciones de Slack o SMS, también deberías revisar los prerequisitos para el manejador de notificaciones relevante.

Si prefieres ser notificado cuando una de tus colas tenga un largo tiempo de inactividad, puedes usar los métodos Horizon::routeMailNotificationsTo, Horizon::routeSlackNotificationsTo y Horizon::routeSmsNotificationsTo. Puedes ejecutar estos métodos desde el HorizonServiceProvider de tu aplicación:

Horizon::routeMailNotificationsTo('[email protected]');
Horizon::routeSlackNotificationsTo('slack-webhook-url', '#channel');
Horizon::routeSmsNotificationsTo('15556667777');

Configurando las notificaciones de umbrales de tiempo de inactividad

Puedes configurar cuántos segundos son considerados como «tiempo de inactividad» dentro de tu archivo de configuración config/horizon.php. La opción de configuración waits dentro de este archivo permite que controles el umbral de tiempo de inactividad para cada combinación conexión / cola:

'waits' => [
    'redis:default' => 60,
],

Métricas

Horizon incluye un panel de control de métricas, el cual proporciona información de los tiempos de espera de tu trabajo y cola, y la tasa de rendimiento. Con el propósito de agregar contenido a este panel, deberías configurar el comando Artisan snapshot de Horizon para que se ejecute cada 5 minutos por medio del planificador de tu aplicación:

/**
* Define the application's command schedule.
*
* @param  \Illuminate\Console\Scheduling\Schedule  $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
    $schedule->command('horizon:snapshot')->everyFiveMinutes();
}

Regístrate hoy en Styde y obtén acceso a todo nuestro contenido.

Lección anterior Laravel Envoy - Documentación de Laravel 6 Lección siguiente Laravel Passport - Documentación de Laravel 6