Horizon

Introduzione

Prima di iniziare con Laravel Horizon, è consigliabile conoscere i servizi di base per le code di Laravel. Horizon aggiunge funzionalità extra alle queue di Laravel che potrebbero risultare complicate se non conosci già le funzionalità base offerte da Laravel.

Laravel Horizon offre una dashboard intuitiva e una configurazione basata su codice per le tue Redis queues di Laravel. Horizon ti permette di monitorare facilmente metriche importanti del tuo sistema di queue, come il numero di job, i tempi di esecuzione e i fallimenti dei job.

Usando Horizon, tutta la configurazione dei worker delle queue è memorizzata in un unico file semplice. Definendo la configurazione dei worker della tua applicazione in un file sotto controllo delle versioni, puoi facilmente scalare o modificare i worker delle queue durante il deploy della tua applicazione.

Installazione

Laravel Horizon richiede l’uso di Redis per gestire la coda. Assicurati quindi che la connessione della coda sia impostata su redis nel file di configurazione config/queue.php della tua applicazione.

Puoi installare Horizon nel tuo progetto usando il gestore di pacchetti Composer:

composer require laravel/horizon

Dopo aver installato Horizon, pubblica le sue risorse usando il comando Artisan horizon:install:

php artisan horizon:install

Configurazione

Dopo aver pubblicato le risorse di Horizon, il file di configurazione principale si troverà in config/horizon.php. Questo file ti permette di configurare le opzioni dei worker delle code per la tua applicazione. Ogni opzione di configurazione include una descrizione del suo scopo, quindi assicurati di esplorare bene questo file.

Horizon utilizza internamente una connessione Redis chiamata horizon. Questo nome di connessione Redis è riservato e non deve essere assegnato a un’altra connessione Redis nel file di configurazione database.php o come valore dell’opzione use nel file di configurazione horizon.php.

Ambienti

Dopo l’installazione, l’opzione principale di configurazione di Horizon con cui dovresti familiarizzare è l’opzione environments. Questa opzione di configurazione è un array di ambienti su cui gira la tua applicazione e definisce le opzioni dei processi worker per ciascun ambiente. Di default, questa voce contiene gli ambienti production e local. Tuttavia, sei libero di aggiungere altri ambienti secondo necessità:

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

        'local' => [
            'supervisor-1' => [
                'maxProcesses' => 3,
            ],
        ],
    ],

Puoi anche definire un ambiente wildcard (*) che verrà usato quando non viene trovato nessun altro ambiente corrispondente:

    'environments' => [
        // ...

        '*' => [
            'supervisor-1' => [
                'maxProcesses' => 3,
            ],
        ],
    ],

Quando avvii Horizon, utilizzerà le opzioni di configurazione dei processi worker per l’ambiente su cui sta girando la tua applicazione. Tipicamente, l’ambiente è determinato dal valore della variabile di ambiente APP_ENV variabile di ambiente. Ad esempio, l’ambiente di Horizon predefinito local è configurato per avviare tre processi worker e bilanciare automaticamente il numero di processi worker assegnati a ciascuna coda. L’ambiente predefinito production è configurato per avviare un massimo di 10 processi worker e bilanciare automaticamente il numero di processi worker assegnati a ciascuna coda.

Devi assicurarti che la sezione environments del tuo file di configurazione horizon contenga una voce per ogni ambiente su cui prevedi di eseguire Horizon.

Supervisors

Come puoi vedere nel file di configurazione predefinito di Horizon, ogni ambiente può contenere uno o più "supervisors". Per impostazione predefinita, il file di configurazione definisce questo supervisor come supervisor-1; tuttavia, sei libero di nominare i tuoi supervisors come preferisci. Ogni supervisor è essenzialmente responsabile della "supervisione" di un gruppo di processi worker e si occupa di bilanciare i processi worker tra le code.

Puoi aggiungere supervisors aggiuntivi a un determinato ambiente se desideri definire un nuovo gruppo di processi worker che devono essere eseguiti in quell’ambiente. Puoi scegliere di farlo se desideri definire una strategia di bilanciamento diversa o un numero diverso di processi worker per una determinata coda utilizzata dalla tua applicazione.

Modalità di Manutenzione

Quando la tua applicazione è in modalità di manutenzione, i job in coda non verranno elaborati da Horizon a meno che l’opzione force del supervisore non sia definita come true nel file di configurazione di Horizon:

    'environments' => [
        'production' => [
            'supervisor-1' => [
                // ...
                'force' => true,
            ],
        ],
    ],

Valori Predefiniti

Nel file di configurazione predefinito di Horizon, noterai un’opzione di configurazione chiamata defaults. Questa opzione specifica i valori predefiniti per i supervisors della tua applicazione. I valori predefiniti del supervisore verranno uniti alla configurazione del supervisore per ogni ambiente, permettendoti di evitare ripetizioni inutili quando definisci i tuoi supervisors.

Strategie di Bilanciamento

A differenza del sistema di code predefinito di Laravel, Horizon permette di scegliere tra tre strategie di bilanciamento dei lavoratori: simple, auto e false. La strategia simple divide i nuovi lavori equamente tra i processi dei lavoratori:

'balance' => 'simple',

La strategia auto, che è predefinita nel file di configurazione, regola il numero di processi dei lavoratori per coda in base al carico di lavoro attuale della coda. Ad esempio, se la tua coda notifications ha 1.000 lavori in sospeso mentre la coda render è vuota, Horizon assegnerà più lavoratori alla coda notifications fino a quando la coda non sarà vuota.

Quando si utilizza la strategia auto, è possibile definire le opzioni di configurazione minProcesses e maxProcesses per controllare il numero minimo di processi per coda e il numero massimo totale di processi dei lavoratori a cui Horizon deve scalare su e giù:

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

Il valore di configurazione autoScalingStrategy determina se Horizon assegnerà più processi dei lavoratori alle code in base al tempo totale necessario per svuotare la coda (time strategia) o al numero totale di lavori nella coda (size strategia).

I valori di configurazione balanceMaxShift e balanceCooldown determinano la velocità con cui Horizon scalerà per soddisfare la domanda dei lavoratori. Nell’esempio sopra, verrà creato o distrutto un massimo di un nuovo processo ogni tre secondi. Puoi modificare questi valori secondo le necessità della tua applicazione.

Quando l’opzione balance è impostata su false, verrà utilizzato il comportamento predefinito di Laravel, in cui le code vengono elaborate nell’ordine in cui sono elencate nella tua configurazione.

Dashboard Authorization

La dashboard di Horizon può essere accessibile tramite la route /horizon. Per impostazione predefinita, potrai accedere a questa dashboard solo nell’ambiente local. Tuttavia, nel tuo file app/Providers/HorizonServiceProvider.php, c’è una definizione di authorization gate. Questa authorization gate controlla l’accesso a Horizon negli ambienti non-local. Sei libero di modificare questa gate come necessario per restringere l’accesso alla tua installazione di Horizon:

/**
 * Register the Horizon gate.
 *
 * Questa gate determina chi può accedere a Horizon negli ambienti non-local.
 */
protected function gate(): void
{
    Gate::define('viewHorizon', function (User $user) {
        return in_array($user->email, [
            'taylor@laravel.com',
        ]);
    });
}

Strategie alternative di autenticazione

Ricorda che Laravel inietta automaticamente l’utente autenticato nella closure del gate. Se la tua applicazione fornisce la sicurezza di Horizon tramite un altro metodo, come le restrizioni IP, allora i tuoi utenti di Horizon potrebbero non aver bisogno di "login". Pertanto, dovrai modificare la firma della closure function (User $user) sopra in function (User $user = null) per forzare Laravel a non richiedere l’autenticazione.

Job Silenziati

A volte, potresti non essere interessato a visualizzare determinati job eseguiti dalla tua applicazione o dai pacchetti di terze parti. Invece di permettere a questi job di occupare spazio nella lista dei "Job Completati", puoi silenziarli. Per iniziare, aggiungi il nome della classe del job all’opzione di configurazione silenced nel file di configurazione horizon della tua applicazione:

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

In alternativa, il job che desideri silenziare può implementare l’interfaccia Laravel\Horizon\Contracts\Silenced. Se un job implementa questa interfaccia, sarà automaticamente silenziato, anche se non è presente nell’array di configurazione silenced:

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

Aggiornare Horizon

Quando aggiorni a una nuova versione principale di Horizon, è importante che tu riveda attentamente la guida all’aggiornamento.

Esecuzione di Horizon

Una volta configurati i tuoi supervisors e workers nel file di configurazione config/horizon.php della tua applicazione, puoi avviare Horizon utilizzando il comando Artisan horizon. Questo singolo comando avvierà tutti i processi worker configurati per l’ambiente attuale:

php artisan horizon

Puoi mettere in pausa il processo di Horizon e istruirlo a continuare l’elaborazione dei job utilizzando i comandi Artisan horizon:pause e horizon:continue:

php artisan horizon:pause

php artisan horizon:continue

Puoi anche mettere in pausa e continuare specifici supervisors di Horizon utilizzando i comandi Artisan horizon:pause-supervisor e horizon:continue-supervisor:

php artisan horizon:pause-supervisor supervisor-1

php artisan horizon:continue-supervisor supervisor-1

Puoi verificare lo stato attuale del processo di Horizon utilizzando il comando Artisan horizon:status:

php artisan horizon:status

Puoi verificare lo stato attuale di uno specifico supervisor di Horizon utilizzando il comando Artisan horizon:supervisor-status:

php artisan horizon:supervisor-status supervisor-1

Puoi terminare in modo elegante il processo di Horizon utilizzando il comando Artisan horizon:terminate. Eventuali job che sono attualmente in elaborazione verranno completati e poi Horizon smetterà di eseguire:

php artisan horizon:terminate

Distribuire Horizon

Quando sei pronto a distribuire Horizon sul server effettivo della tua applicazione, dovresti configurare un monitor di processo per controllare il comando php artisan horizon e riavviarlo se si interrompe inaspettatamente. Non preoccuparti, parleremo di come installare un monitor di processo più avanti.

Durante il processo di distribuzione della tua applicazione, dovresti istruire il processo Horizon a terminare in modo che venga riavviato dal monitor di processo e riceva le modifiche al codice:

php artisan horizon:terminate

Installazione Supervisor

Supervisor è un monitor di processi per il sistema operativo Linux e riavvierà automaticamente il tuo processo horizon se smette di funzionare. Per installare Supervisor su Ubuntu, puoi usare il comando seguente. Se non usi Ubuntu, probabilmente puoi installare Supervisor usando il gestore di pacchetti del tuo sistema operativo:

sudo apt-get install supervisor

Se configurare Supervisor da solo ti sembra complicato, considera di usare Laravel Forge, che installerà e configurerà automaticamente Supervisor per i tuoi progetti Laravel.

Configurazione di Supervisor

I file di configurazione di Supervisor sono solitamente memorizzati nella directory /etc/supervisor/conf.d del tuo server. In questa directory, puoi creare qualsiasi numero di file di configurazione che istruiscono Supervisor su come monitorare i tuoi processi. Ad esempio, creiamo un file horizon.conf che avvia e monitora un processo 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

Quando definisci la configurazione di Supervisor, assicurati che il valore di stopwaitsecs sia maggiore del numero di secondi consumati dal tuo job a più lunga esecuzione. Altrimenti, Supervisor potrebbe terminare il job prima che abbia finito l’elaborazione.

Sebbene gli esempi sopra siano validi per server basati su Ubuntu, la posizione e l’estensione dei file di configurazione di Supervisor possono variare tra altri sistemi operativi server. Consulta la documentazione del tuo server per maggiori informazioni.

Avviare Supervisor

Una volta creato il file di configurazione, puoi aggiornare la configurazione di Supervisor e avviare i processi monitorati utilizzando i seguenti comandi:

sudo supervisorctl reread

sudo supervisorctl update

sudo supervisorctl start horizon

Per maggiori informazioni su come eseguire Supervisor, consulta la documentazione di Supervisor.

Tag

Horizon consente di assegnare "tag" ai job, inclusi mailables, eventi broadcast, notifiche e listener di eventi in coda. In effetti, Horizon etichetterà in modo intelligente e automatico la maggior parte dei job a seconda dei modelli Eloquent associati al job. Ad esempio, dai un’occhiata al seguente job:

<?php

namespace App\Jobs;

use App\Models\Video;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;

class RenderVideo implements ShouldQueue
{
    use Queueable;

    /**
     * Crea una nuova istanza del job.
     */
    public function __construct(
        public Video $video,
    ) {}

    /**
     * Esegue il job.
     */
    public function handle(): void
    {
        // ...
    }
}

Se questo job viene messo in coda con un’istanza di App\Models\Video che ha un attributo id pari a 1, riceverà automaticamente il tag App\Models\Video:1. Questo perché Horizon cercherà nelle proprietà del job eventuali modelli Eloquent. Se vengono trovati modelli Eloquent, Horizon etichetterà in modo intelligente il job utilizzando il nome della classe del modello e la chiave primaria:

use App\Jobs\RenderVideo;
use App\Models\Video;

$video = Video::find(1);

RenderVideo::dispatch($video);

Assegnare Tag Manualmente ai Job

Se desideri definire manualmente i tag per uno dei tuoi oggetti in coda, puoi definire un metodo tags nella classe:

class RenderVideo implements ShouldQueue
{
    /**
     * Ottieni i tag da assegnare al job.
     *
     * @return array<int, string>
     */
    public function tags(): array
    {
        return ['render', 'video:'.$this->video->id];
    }
}

Assegnare manualmente tag ai Listener degli Eventi

Quando si recuperano i tag per un listener di eventi in coda, Horizon passerà automaticamente l’istanza dell’evento al metodo tags, permettendoti di aggiungere dati dell’evento ai tag:

class SendRenderNotifications implements ShouldQueue
{
    /**
     * Ottieni i tags che devono essere assegnati al listener.
     *
     * @return array<int, string>
     */
    public function tags(VideoRendered $event): array
    {
        return ['video:'.$event->video->id];
    }
}

Notifiche

Quando configuri Horizon per inviare notifiche tramite Slack o SMS, dovresti rivedere i requisiti per il canale di notifica pertinente.

Se desideri essere notificato quando una delle tue code ha tempi di attesa lunghi, puoi usare i metodi Horizon::routeMailNotificationsTo, Horizon::routeSlackNotificationsTo e Horizon::routeSmsNotificationsTo. Puoi chiamare questi metodi dal metodo boot del App\Providers\HorizonServiceProvider della tua applicazione:

    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        parent::boot();

        Horizon::routeSmsNotificationsTo('15556667777');
        Horizon::routeMailNotificationsTo('example@example.com');
        Horizon::routeSlackNotificationsTo('slack-webhook-url', '#channel');
    }

Configurazione delle Soglie di Tempo di Attesa delle Notifiche

Puoi configurare quanti secondi sono considerati un "attesa lunga" nel file di configurazione config/horizon.php della tua applicazione. L’opzione di configurazione waits in questo file ti permette di controllare la soglia di attesa lunga per ogni combinazione di connessione/coda. Qualsiasi combinazione di connessione/coda non definita avrà una soglia di attesa lunga predefinita di 60 secondi:

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

Metriche

Horizon include una dashboard delle metriche che fornisce informazioni sui tempi di attesa e il throughput dei tuoi job e delle code. Per popolare questa dashboard, dovresti configurare il comando snapshot di Artisan di Horizon per eseguire ogni cinque minuti nel file routes/console.php della tua applicazione:

    use Illuminate\Support\Facades\Schedule;

    Schedule::command('horizon:snapshot')->everyFiveMinutes();

Cancellare i Job Falliti

Se desideri cancellare un job fallito, puoi usare il comando horizon:forget. Il comando horizon:forget accetta l’ID o l’UUID del job fallito come unico argomento:

php artisan horizon:forget 5

Se desideri cancellare tutti i job falliti, puoi usare l’opzione --all con il comando horizon:forget:

php artisan horizon:forget --all

Cancellare i Job dalle Code

Se vuoi eliminare tutti i job dalla coda predefinita della tua applicazione, puoi farlo usando il comando Artisan horizon:clear:

php artisan horizon:clear

Puoi usare l’opzione queue per eliminare i job da una coda specifica:

php artisan horizon:clear --queue=emails
Lascia un commento

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *