Cos’è Horizon
Laravel Horizon è la dashboard di monitoraggio dedicata alle code Redis di Laravel. Visualizza in tempo reale throughput, tempi di esecuzione e fallimenti dei job e gestisci la configurazione dei worker via codice.
Horizon estende le funzionalità di base delle code. Consulta prima Code e job e assicurati che sia disponibile Redis .
Installazione
Horizon usa Redis. Verifica che QUEUE_CONNECTION in config/queue.php sia redis. Al momento non supporta Redis Cluster.
Installazione:
composer require laravel/horizon
Pubblica asset e configurazione:
php artisan horizon:install
Vengono generati config/horizon.php e app/Providers/HorizonServiceProvider.php.
Configurazione
Struttura di config/horizon.php
config/horizon.php gestisce le impostazioni dei worker. Il centro è environments.
'environments' => [
'production' => [
'supervisor-1' => [
'connection' => 'redis' ,
'queue' => [ 'default' , 'notifications' ],
'balance' => 'auto' ,
'autoScalingStrategy' => 'time' ,
'minProcesses' => 1 ,
'maxProcesses' => 10 ,
'balanceMaxShift' => 1 ,
'balanceCooldown' => 3 ,
'tries' => 3 ,
'timeout' => 60 ,
],
],
'local' => [
'supervisor-1' => [
'maxProcesses' => 3 ,
],
],
],
Horizon usa internamente una connessione Redis chiamata horizon. Non riutilizzare questo nome in config/database.php.
Supervisor
Ogni environment ha uno o più “supervisor”. Sono unità di gestione dei worker: puoi avere più supervisor con diverse code, strategie e numero di processi.
Default
Con defaults imposti valori comuni a tutti i supervisor.
'defaults' => [
'supervisor-1' => [
'connection' => 'redis' ,
'queue' => [ 'default' ],
'balance' => 'auto' ,
'tries' => 1 ,
'timeout' => 60 ,
'maxProcesses' => 1 ,
],
],
Modalità manutenzione
Di default Horizon non elabora job in manutenzione. Con force sì.
'environments' => [
'production' => [
'supervisor-1' => [
'force' => true ,
],
],
],
Tentativi
'environments' => [
'production' => [
'supervisor-1' => [
'tries' => 10 ,
],
],
],
0 = tentativi illimitati.
Timeout
'environments' => [
'production' => [
'supervisor-1' => [
'timeout' => 60 ,
],
],
],
timeout deve essere qualche secondo minore di retry_after in config/queue.php. La strategia auto può terminare job più lunghi.
Backoff
// Fisso
'backoff' => 10 ,
// Esponenziale
'backoff' => [ 1 , 5 , 10 ],
Strategie di bilanciamento
Regola il numero di worker in base al carico. 'supervisor-1' => [
'balance' => 'auto' ,
'autoScalingStrategy' => 'time' , // o 'size'
'minProcesses' => 1 ,
'maxProcesses' => 10 ,
'balanceMaxShift' => 1 ,
'balanceCooldown' => 3 ,
],
time — tempo stimato per svuotare la coda
size — numero di job in coda
Con auto l’ordine delle code non implica priorità. Per priorità stretta usa più supervisor.
Numero di worker fisso, distribuiti tra le code. 'supervisor-1' => [
'balance' => 'simple' ,
'processes' => 10 ,
'queue' => [ 'default' , 'notifications' ],
],
5 processi per coda.
false (nessun bilanciamento)
Priorità stretta secondo l’ordine delle code. 'supervisor-1' => [
'balance' => false ,
'queue' => [ 'default' , 'notifications' ],
'minProcesses' => 1 ,
'maxProcesses' => 10 ,
],
default sempre prima di notifications.
Autorizzazione della dashboard
La dashboard è su /horizon. In locale è accessibile a tutti; in produzione limita con una gate.
Modifica gate() in app/Providers/HorizonServiceProvider.php.
use App\Models\ User ;
use Illuminate\Support\Facades\ Gate ;
protected function gate () : void
{
Gate :: define ( 'viewHorizon' , function ( User $user ) {
return in_array ( $user -> email , [
'[email protected] ' ,
]);
});
}
Senza autenticazione (protetto da IP, ad esempio):
Gate :: define ( 'viewHorizon' , function ( User $user = null ) {
return true ;
});
Avvio di Horizon
Comandi base
# Avvio
php artisan horizon
# Pausa / ripresa
php artisan horizon:pause
php artisan horizon:continue
# Per supervisor
php artisan horizon:pause-supervisor supervisor-1
php artisan horizon:continue-supervisor supervisor-1
# Stato
php artisan horizon:status
php artisan horizon:supervisor-status supervisor-1
# Terminazione graceful
php artisan horizon:terminate
Sviluppo locale: auto-restart
npm install --save-dev chokidar
php artisan horizon:listen
# In Docker/Vagrant
php artisan horizon:listen --poll
Supervisor in produzione
Installazione:
sudo apt-get install supervisor
Configurazione (/etc/supervisor/conf.d/horizon.conf):
[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
Imposta stopwaitsecs più alto del job più lungo.
Avvio:
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start horizon
Al deploy, riavvia Horizon:
php artisan horizon:terminate
Con Supervisor autostart=true/autorestart=true, si riavvia da solo.
Gestione dei job
Tag
Horizon aggiunge automaticamente tag ai job in base ai modelli Eloquent che ricevono.
// Video (id=1) → tag "App\Models\Video:1"
RenderVideo :: dispatch ( Video :: find ( 1 ));
Tag manuali via tags():
class RenderVideo implements ShouldQueue
{
public function tags () : array
{
return [ 'render' , 'video:' . $this -> video -> id ];
}
}
Nei listener l’evento viene passato a tags().
class SendRenderNotifications implements ShouldQueue
{
public function tags ( VideoRendered $event ) : array
{
return [ 'video:' . $event -> video -> id ];
}
}
Silenziare job
In config/horizon.php:
'silenced' => [
App\Jobs\ ProcessPodcast :: class ,
],
'silenced_tags' => [
'notifications' ,
],
Oppure implementa Silenced.
use Laravel\Horizon\Contracts\ Silenced ;
class ProcessPodcast implements ShouldQueue , Silenced
{
use Queueable ;
}
Metriche e monitoraggio
Pianifica gli snapshot:
use Illuminate\Support\Facades\ Schedule ;
Schedule :: command ( 'horizon:snapshot' ) -> everyFiveMinutes ();
Per cancellare le metriche:
php artisan horizon:clear-metrics
Notifiche dei fallimenti
Notifiche per attese troppo lunghe. In boot() di HorizonServiceProvider:
use Laravel\Horizon\ Horizon ;
public function boot () : void
{
parent :: boot ();
Horizon :: routeMailNotificationsTo ( '[email protected] ' );
Horizon :: routeSlackNotificationsTo ( 'slack-webhook-url' , '#ops' );
Horizon :: routeSmsNotificationsTo ( '15556667777' );
}
Soglie di attesa
In config/horizon.php:
'waits' => [
'redis:critical' => 30 ,
'redis:default' => 60 ,
'redis:batch' => 120 ,
],
0 disabilita.
Job falliti
# Elimina uno specifico
php artisan horizon:forget 5
# Elimina tutti i falliti
php artisan horizon:forget --all
Svuotare code:
php artisan horizon:clear
php artisan horizon:clear --queue=emails
Aggiornamento
Consulta sempre la Guida all’upgrade .
Pagine correlate
Code e job Le basi delle code Laravel: creazione, dispatch, batch e gestione fallimenti.
Redis Configurazione e uso di Redis, backend necessario per Horizon.