← Nicola VitraniScrivimi

Note dal lavoro · Backend

Code e job in Laravel: spostare il lavoro lento fuori dalla richiesta

Backend · 5 min di lettura

Inviare un’email, generare un PDF o chiamare un servizio esterno dentro una richiesta web fa aspettare l’utente per cose che non gli servono subito. In Laravel le code spostano quel lavoro in secondo piano.

Il flusso di base

// in un controller
SendWelcomeEmail::dispatch($user);

// il job
class SendWelcomeEmail implements ShouldQueue
{
    use Queueable, SerializesModels;

    public int $tries = 3;
    public array $backoff = [30, 120];

    public function __construct(public User $user) {}

    public function handle(): void
    {
        // invia l'email
    }
}

La richiesta risponde subito, e un processo separato (php artisan queue:work) prende i job dalla coda ed esegue handle().

Scegliere il driver

  • database: il più semplice da avviare, usa una tabella. Va bene per volumi bassi.
  • redis: più veloce e adatto a carichi più alti.
  • sync: esegue subito, senza coda. Utile nei test, non in produzione.

Tentativi, attese e fallimenti

  • $tries e $backoff definiscono quante volte riprovare e quanto aspettare tra un tentativo e l’altro.
  • I job che falliscono definitivamente finiscono nella tabella failed_jobs, da rivedere con php artisan queue:failed e rilanciare con queue:retry.
  • Un job può essere eseguito più di una volta: scrivilo in modo idempotente, in modo che un secondo passaggio non faccia danni.

In produzione

  • Il worker deve restare sempre acceso: lo si tiene in vita con un supervisore come Supervisor o con il servizio della piattaforma.
  • Dopo ogni deploy esegui php artisan queue:restart, perché i worker in memoria hanno ancora il vecchio codice.
  • SerializesModels salva solo l’identificativo del modello: il job lo ricarica quando parte. Considera che i dati possono essere cambiati nel frattempo.
  • Monitora la lunghezza della coda: se cresce sempre, i worker non bastano.