Come mettere in pausa e controllare le code in Laravel passo dopo passo

Ultimo aggiornamento: Dicembre 5 2025
  • Laravel offre un'API di coda unificata con più driver (database, Redis, SQS...) e separazione tra connessioni e code logiche.
  • I lavori consentono di spostare in background le attività più impegnative, con supporto per modelli di serializzazione, middleware, lavori una tantum, crittografia, batch e stringhe.
  • I lavoratori vengono gestiti tramite queue:work, Supervisor e comandi quali queue:pause/queue:continue, controllando i tentativi, i timeout e le priorità.
  • Esiste un ecosistema completo per errori, monitoraggio e test (failed_jobs, queue:retry, queue:monitor, Queue::fake) che rende le code affidabili in produzione.

Gestione delle code in Laravel

Lavorare con le code in Laravel è quasi obbligatorio in qualsiasi progetto che si rispetti: inviare email, elaborare file CSV, generare PDF, ridimensionare immagini, chiamare API esterne... Se tutto ciò viene fatto nella richiesta HTTP principale, il sito web rallenta, compaiono errori 500 e l'utente si ritrova a fissare disperatamente una schermata vuota.

La buona notizia è che Laravel offre un'infrastruttura di accodamento potente e flessibile che consente di delegare le operazioni più complesse ai processi in background, gestirli per priorità, raggrupparli in batch, monitorarli, riprovarli in caso di errore e persino sospenderli temporaneamente per manutenzione. Analizziamo nel dettaglio come sfruttarla al meglio, compresi i metodi per sospenderla, riprenderla e controllarne il comportamento in produzione.

Concetti di base: connessioni, code e driver

In Laravel, prima di mettere in pausa qualsiasi cosa, è necessario comprendere la differenza tra connessioni di coda e code stesse. In config/queue.php hai una matrice connections dove definisci ogni backend: database, redis, beanstalkd, sqs, sync, null, failover, rabbitmq (se lo aggiungi), ecc.

Ogni connessione può avere più code logiche (nomi come default, emails, high, low, importsL'attributo queue Ogni connessione indica qual è la coda predefinita in cui verranno indirizzati i processi se non ne viene specificata un'altra. onQueue()In questo modo puoi fare cose come:

  • Una coda veloce per e-mail o transazioni brevi.
  • Un'altra bassa priorità per attività lunghe come l'elaborazione di video o report di grandi dimensioni.
  • Code segmentate per tipo di attività: imports, notificaciones, reportes, ecc.

Quando si avvia il lavoratore con php artisan queue:workPer impostazione predefinita, ascolta la coda specificata come predefinito sulla connessione selezionata. Se si desidera stabilire una priorità, è possibile passare più code separate da virgole:

php artisan queue:work redis --queue=high,default,low

In questo modo, il worker elabora prima le priorità più alte , poi quelle predefinite e solo infine quelle più basse , il che è fondamentale quando il sistema è sovraccarico e non si vuole che un report di 30 minuti blocchi le email ad alta priorità.

Driver di coda e prerequisiti

Laravel offre un'API unificata per diversi driver di coda , ma ognuno ha le proprie caratteristiche e dipendenze specifiche. Scegliere il driver giusto è fondamentale prima di parlare di come mettere in pausa i worker.

Banca dati dei conducenti

L'autista banca dati Memorizza i lavori in una tabella SQL (di solito jobsÈ facile da configurare ed è perfetto per piccoli progetti o ambienti di sviluppo in cui non si vuole perdere tempo con Redis o SQS.

Passi di base:

  • Generare la migrazione: php artisan queue:table (o nelle versioni più recenti, si presenta come create_jobs_table predefinito).
  • Eseguire le migrazioni: php artisan migrate.
  • Configurare QUEUE_CONNECTION=database in .env e confermare in config/queue.php che 'default' => env('QUEUE_CONNECTION','database').

È comodo e sufficientemente robusto, ma con molte code e un traffico elevato può diventare un collo di bottiglia , poiché tutto passa attraverso lo stesso database relazionale.

Autista Redis

Il driver Redis è lo standard di riferimento negli ambienti di produzione. È veloce, supporta funzionalità avanzate (blocco, limitazione della velocità, blocchi atomici, Horizon, ecc.) e si adatta molto bene alle diverse esigenze.

Punti importanti:

  • È necessario configurare la connessione Redis in config/database.php.
  • Le opzioni serializer y compression da Redis Non sono compatibili con il gestore della coda.
  • Se usi Redis ClusterI nomi delle code devono avere un hashtag, ad esempio {default}in modo che tutte le chiavi in ​​quella coda cadano nello stesso slot.
  • l'opzione block_for Permette al lavoratore di bloccarsi mentre attende i lavori per alcuni secondi, invece di effettuare continuamente il polling: risparmia CPU e riduce le query al server Redis.

Ad esempio:

'redis' => ,

Se metti blocco_per = 0Il lavoratore rimane bloccato a tempo indeterminato finché non diventa disponibile un lavoro, cosa da tenere a mente se si desidera che risponda rapidamente a segnali come SIGTERM o mettere in pausa i comandi.

Altri driver: SQS, Beanstalkd, null, failover…

Oltre ai database e a Redis, Laravel supporta altri sistemi :

  • Amazon SQSCode gestite su AWS, con supporto per FIFOGruppi di messaggi, deduplicazione e impostazioni di visibilità avanzate. Richiede l'SDK. aws/aws-sdk-php.
  • BeanstalkdMolto veloce e facile, utilizzando il pacchetto pda/pheanstalk.
  • sync: esegue i compiti inmediatamente nello stesso processo. Utile nello sviluppo o nei test, ma in produzione è praticamente come non usare affatto le code.
  • nullo: scarta i lavori non appena vengono "spediti". Utilizzato per disattivare completamente il sistema di accodamento.
  • failoverCiò consente di configurare più connessioni e, se quella primaria fallisce, Laravel tenta di inviare il processo a quella successiva nell'elenco. Perfetto per ambienti in cui alta disponibilità È fondamentale.
  Electron JS: tutto quello che devi sapere

A livello di sospensione e ripresa dei worker, la logica è praticamente la stessa indipendentemente dal driver, perché viene gestita dai comandi Artisan e dalla classe Worker , non dal backend della coda.

Creazione di posti di lavoro e serializzazione del modello

Un Lavoro In Laravel, è semplicemente una classe che incapsula un'attività da eseguire in una coda. In genere viene generata con Artisan e salvata in app/Jobs.

Per crearne uno:

php artisan make:job ProcessPodcast

La classe generata attrezzi ShouldQueue e di solito usa tratti Dispatchable, InteractsWithQueue, Queueable y SerializesModelsIl cuore è nel metodo handle()che è ciò che fa il lavoratore quando arriva il lavoro.

Una funzionalità particolarmente potente è la serializzazione automatica dei modelli Eloquent . Se si accetta un modello nel costruttore del Job, Laravel non aggiunge l'intero oggetto alla coda, ma solo il suo identificatore. Quando il job viene elaborato, ricostruisce il modello dal database con le relative relazioni caricate.

Esempio tipico (in pseudocodice, per evitare di ripeterlo alla lettera):

  • Il costruttore riceve Podcast $podcast.
  • Il tratto SerializesModels È responsabile del salvataggio dell'ID.
  • En handle(AudioProcessor $processor) Tu fai il lavoro più duro (ad esempio, elaborare l'audio).

Se non si desidera che le relazioni in un modello siano serializzate (in modo che il payload non sia enorme), è possibile utilizzare $model->withoutRelations() o in PHP 8 l'attributo # sulla proprietà promossa dal costruttore.

Iniezione di dipendenza nel metodo handle

Un altro vantaggio è che puoi iniettare i servizi direttamente nel metodo handle (come se fosse un controller), perché Laravel utilizza anche il contenitore di servizi in Jobs. Ad esempio, è possibile richiedere un AudioProcessorClient HTTP, repository, ecc. e il framework si occupa di risolverli.

Se hai bisogno di un controllo ultra-fine di quello che viene chiamato handle, Puoi usare Container::bindMethod() in un fornitore di servizi e definire autonomamente la logica di iniezione, ma nella maggior parte dei casi non è necessario complicare così tanto le cose.

Middleware di lavoro

Proprio come i percorsi hanno un middleware, anche i lavori possono avere middleware specifico che vengono eseguiti prima e dopo il lavoro. Ciò riduce notevolmente il codice ripetitivo nei metodi handle() ed è particolarmente utile per:

  • Limitazione della velocità con Redis.
  • Evitare si sovrappone di opere che toccano la stessa risorsa.
  • Eccezioni regolari per API instabili.
  • Saltare i lavori in determinate condizioni (Skip middleware).

Il middleware è solitamente posizionato in app/Jobs/Middleware e vengono restituiti dal metodo middleware() Da Giobbe. Esempio concettuale:

public function middleware(): array { return ;

Tipi speciali di lavori: unici, crittografati e bloccati

Laravel ti consente di contrassegnare determinati lavori come unico per garantire che due istanze identiche non vengano mai messe in coda contemporaneamente. Ciò si ottiene implementando l'interfaccia ShouldBeUnique o ShouldBeUniqueUntilProcessinge supporta la definizione di una chiave uniqueId() e un tempo uniqueFor.

Questa è la soluzione ideale per cose come:

  • Ricalcola l'indice di ricerca di un prodotto: solo una volta per prodotto finché non sarà finita.
  • Sincronizzazioni con servizi esterni che non consentono richieste simultanee per la stessa risorsa.

Sotto, Laravel usa un serratura atomica di cache (Redis, memcached, database, ecc.). Puoi anche scegliere il driver della cache per quel blocco con uniqueVia().

Inoltre, c'è l'interfaccia ShouldBeEncrypted, con cui indichi che il lavoro completo è Inserisci il tuo codice prima di entrare nella codaMolto utile quando si passano dati sensibili e non si vuole che vengano trasmessi in formato testo normale tramite Redis, SQS o il database.

Inviare, ritardare ed eseguire lavori in diverse modalità

Una volta definito il tuo lavoro, lo avvii con Job::dispatch() da controller, ascoltatori di eventi, comandi Artisan o persino chiusure. I parametri che passi a dispatch Si rivolgono direttamente al costruttore di Giobbe.

Varianti interessanti:

  • dispatchIf() y dispatchUnless() per condizionare la spedizione in un'unica linea.
  • delay() in modo che il lavoro non possa essere elaborato fino a una data/ora specifica.
  • dispatchAfterResponse() o afterResponse() en dispatch() Chiusure, che rimandano l'esecuzione finché non viene inviata la risposta HTTP, ma all'interno dello stesso processo PHP.
  • dispatchSync() per eseguire il Job in modo sincrono (senza passare dalla coda) ma riutilizzando la stessa classe.
  • Collegamenti speciali come deferred o background da eseguire dopo la risposta, nello stesso processo o in un nuovo processo PHP.

Infine, è possibile specificare la connessione e la coda con metodi concatenati onConnection() y onQueue(), sia durante la spedizione che all'interno del Job Builder.

Controllo preciso: nuovi tentativi, backoff, timeout e gestione degli errori

Una parte importante del lavoro con le code in Laravel consiste nel decidere quante volte riprovare un'operazione , quanto tempo aspettare tra un tentativo e l'altro e quando considerarla fallita.

  Chi è uno sviluppatore front-end e cosa fa?

Opzioni disponibili:

  • --tries en queue:work per impostare il numero massimo di tentativi per tutti i lavori di quel worker (a meno che il lavoro non ne definisca uno proprio) $tries o tries()).
  • $tries o un metodo tries() nella classe Job per il controllo per ogni singolo lavoro.
  • retryUntil() per dire: "riprova quanto vuoi fino a questa volta, dopodiché è un fallimento". Se coincide con tries, comando retryUntil.
  • $maxExceptions per interrompere quando il problema è dovuto a ripetute eccezioni non gestite.
  • $timeout o --timeout per indicare quanti secondi può durare un Job prima che il worker interrompa il processo figlio.
  • $failOnTimeout per contrassegnare il lavoro come fallito in caso di timeout.
  • $backoff il metodo backoff() per definire quanto tempo attendere tra i nuovi tentativi, anche con valori esponenziali.

Se un processo genera un'eccezione non rilevata, Laravel... rilascia di nuovo nella coda fino all'esaurimento dei tentativi configurati. È possibile controllarlo manualmente con release($segundos) o fail($exception) quando si desidera contrassegnare deliberatamente un lavoro come fallito.

Lavori non riusciti, tabella failed_jobs e potatura

Quando un Giobbe esaurisce i suoi tentativi, viene considerato lavoro fallito e Laravel lo inserisce nella tabella failed_jobs (o in DynamoDB se lo si configura in questo modo). Questa tabella memorizza UUID, connessione, coda, payload del job ed eccezione generata.

Comandi utili:

  • php artisan queue:failed per elencare quelli falliti.
  • php artisan queue:retry <id|all> per riprovarli.
  • php artisan queue:forget <id> per eliminarne uno.
  • php artisan queue:flush per eliminare tutto (con opzione per le ore nelle versioni più recenti).
  • php artisan queue:prune-failed --hours=48 per eliminare automaticamente i vecchi record.

In Jobs puoi definire un metodo failed(Throwable $exception) Per una pulizia extra: notificare l'utente, annullare azioni parziali, scrivere log specializzati, ecc. Notare che viene creata una nuova istanza del Job per chiamare failed()Pertanto, non fare affidamento sulle modifiche di proprietà apportate in handle().

Batch di lavori: batch di lavori e loro combinazione con stringhe

Quando è necessario avviare centinaia o migliaia di processi correlati (ad esempio, importare un file CSV di grandi dimensioni a blocchi, elaborare file in batch, pulire dati, ecc.), è consigliabile utilizzare la funzionalità batch di Laravel .

Flusso di base:

  • creare la tabella job_batches con php artisan queue:batches-table && php artisan migrate.
  • Contrassegna i lavori che faranno parte dei batch con la caratteristica Batchable.
  • Applica Bus::batch() per inviare un set di lavori, con callback then, catch y finally.
  • Accedi al batch da ogni lavoro con $this->batch() e controlla se è stato annullato.
  • Possibilità di aggiungere più lavori a un batch in corso con $this->batch()->add().

I batch si integrano perfettamente con le catene : è possibile avere catene all'interno di un batch o batch come elementi di una catena più grande. Questo è particolarmente utile quando si desidera che più catene vengano eseguite "in parallelo" e attivino un'azione al termine di ciascuna.

Esecuzione, priorità e distribuzione dei lavoratori

Tutta la magia delle code avviene perché hai uno o più lavoratori eseguendo il comando queue:work (o queue:listen(sebbene quest'ultimo sia meno efficiente). Questi processi sono demoni di lunga durata che ascoltano le rispettive code.

Opzioni chiave di queue:work:

  • Collegamento: php artisan queue:work redis, queue:work database, ecc.
  • Unità: --queue=high,default,low per stabilire le priorità.
  • -undici: elabora un singolo lavoro ed esce.
  • –max-jobs: elabora X lavori e termina (per riavviare periodicamente i worker e liberare memoria).
  • –tempo massimo: elabora per N secondi e poi esce.
  • -sonno: secondi di attesa quando non ci sono lavori disponibili.
  • –fermarsi quando è vuoto: svuota la coda e la chiude in modo pulito (ideale negli ambienti Docker o per lavori una tantum).
  • -tempo scaduto: secondi di timeout per processo, come abbiamo detto prima.
  • -vigore: per elaborare i lavori anche se l'app è in modalità di manutenzione.

Poiché questi processi sono di lunga durata, in produzione si utilizza quasi sempre un monitor di processi come Supervisor (su Linux) per avviare i worker X, riavviarli in caso di arresto anomalo e gestire i log. Un tipico blocco di configurazione di Supervisor per Laravel definisce:

  • command dell' php artisan queue:work ... calcestruzzo.
  • numproc per indicare quanti worker avviare in parallelo.
  • Percorsi di log, utente, riavvii automatici, ecc.

Mettere in pausa e riprendere le code in Laravel

Passiamo ora a un aspetto spesso importante nella manutenzione: come sospendere i processi in coda senza arrestarli bruscamente e senza lasciare attività incompiute. Laravel offre diversi meccanismi, alcuni più recenti, altri più classici, per controllare questo aspetto.

Pausa: segnali di coda:pausa e interruzione

Nelle versioni più recenti, Laravel ha aggiunto comandi specifici per mettere in pausa e riprendere l'esecuzione dei worker:

  • php artisan queue:pause: indica al sistema di smettere di accettare nuovi lavori, ma di lasciare che quelli già in corso vengano completati.
  • php artisan queue:continue: riprende l'elaborazione dei nuovi lavori dal punto in cui era stata interrotta.
  Calcolo del fattore di inflazione della varianza (VIF) in C# e progettazione del software

Questi comandi funzionano inviando segnali ai worker tramite il meccanismo di caching utilizzato internamente da Laravel. Ecco perché è importante avere un driver di cache configurato correttamente (memcached, redis, database, file, ecc.) anche se la coda di cache effettiva è diversa.

Importante: la sospensione di una coda o di un worker non annulla né elimina i processi già in coda ; impedisce semplicemente che altri processi vengano rimossi dalla coda per tutta la durata della sospensione.

Sondaggio delle interruzioni e impatto sulle prestazioni

Ogni volta che un worker termina un'attività, Laravel controlla la cache per i segnali di riavvio, pausa o continuazione . Questo ha un costo trascurabile, ma esiste. Se sei estremamente concentrato sulle prestazioni e sai che non avrai bisogno di mettere in pausa o riavviare i worker tramite comandi, puoi disabilitare questo polling chiamando:

Queue::withoutInterruptionPolling();

Oppure addirittura regolare le proprietà statiche di Illuminate\Queue\Worker per disabilitare tocchi specifici ($riavviabile, $pausableTuttavia, se fai questo e poi provi a usare queue:pause o queue:restarti lavoratori Non lo scoprirannoSi tratta di una decisione progettuale che dovrebbe essere attentamente ponderata.

Metti in pausa manualmente con Supervisor o Docker

Oltre ai comandi di Laravel , negli ambienti di produzione i processi vengono spesso "sospesi" indirettamente:

  • Arresto del programma in Supervisor (supervisorctl stop laravel-worker:*), che uccide o ferma i lavoratori.
  • utilizzando –fermarsi quando è vuoto nelle distribuzioni per consentire ai lavoratori di terminare ciò che è in coda e poi spegnersi.
  • In Docker, lasciare che il contenitore elabori con --stop-when-empty e poi si spegne.

La differenza con queue:pause Arrestando completamente i processi, si interromperà l'elaborazione dei lavori finché i worker non verranno riavviati. pausa interna È possibile mantenere i processi in memoria, in attesa del comando continueQuesta funzionalità è utile per implementazioni rapide di rollback o brevi periodi di manutenzione.

Transazioni del database e after_commit

Un errore classico: inviare processi all'interno di transazioni di database . Se non si presta attenzione, il processo di lavoro potrebbe eseguire il processo prima che venga effettuato il commit, e il modello o i dati attesi potrebbero non essere ancora presenti nel database.

Per evitare questa danza, hai due possibilità:

  • attivare 'after_commit' => true nella configurazione della connessione alla coda. Pertanto, qualsiasi Job distribuito all'interno di una transazione viene posticipato internamente fino alla sua conferma.
  • Utilizzare metodi per lavoro afterCommit() o beforeCommit() durante la distribuzione, per forzare il comportamento solo in Job specifici.

Se la transazione viene annullata, i processi inviati durante essa vengono scartati senza mai entrare nella coda, che è esattamente ciò che solitamente si desidera per mantenere la coerenza.

Monitoraggio, pulizia delle code e test

Una volta che le code sono operative e funzionanti a pieno regime, non basta semplicemente inserire i Job e dimenticarsene; è necessario monitorare e testare il comportamento di tutto il sistema.

Strumenti e comandi utili:

  • queue:clear per svuotare una coda specifica (SQS, Redis, database).
  • queue:monitor per monitorare il numero di lavori in determinate code e attivare l'evento QueueBusy se superano una soglia.
  • Eventi di lavoro come Queue::before, Queue::after, Queue::looping y Queue::failing per agganciare logica personalizzata (log, metriche, rollback, ecc.).
  • Falsi nei test utilizzando Queue::fake() y Bus::fake() per verificare che i lavori, le stringhe o i batch siano stati distribuiti senza effettivamente eseguirli.

Nei test è possibile dichiarare cose come "questo lavoro è stato messo in coda X volte" , "una catena con questi lavori è stata inviata in questo ordine" o "nessun lavoro specifico è stato messo in coda", il che offre un elevato livello di sicurezza nei flussi complessi.

Con questo intero ecosistema, driver come Redis o SQS, lavori ben progettati, middleware per la messa a punto, batch, catene, configurazione dei nuovi tentativi, lavoratori gestiti dal supervisore e comandi come queue:pause y queue:continue— Laravel ti consente di padroneggiare l'elaborazione in background fino al millimetro, dal tipico invio di e-mail alle architetture di code distribuite con failover, garantendo che la tua applicazione continui a rispondere rapidamente a livello HTTP mentre vengono eseguiti lavori pesanti al di sotto, senza bloccare l'utente.

Quadro Laravel
Articolo correlato:
Il potente framework Laravel