Wat is een queue?
In webapplicaties komen taken voor die meerdere seconden duren, zoals het versturen van e-mails, het verkleinen van afbeeldingen of het aanroepen van externe API’s. Als je dit synchroon binnen een HTTP-request doet, moet de gebruiker wachten totdat de response terugkomt. Met Laravel queues kun je zulke zware taken asynchroon op de achtergrond uitvoeren. De request geeft direct een response terug, terwijl een workerproces de eigenlijke taak apart afhandelt.Queues ondersteunen meerdere backends, waaronder database, Redis en Amazon SQS.
In een ontwikkelomgeving kun je de
sync-driver gebruiken om jobs direct uit te voeren zonder queue.Queue-configuratie
config/queue.php
De queue-configuratie staat gebundeld inconfig/queue.php.
Met de omgevingsvariabele QUEUE_CONNECTION schakel je tussen drivers.
.env instellen
De databasedriver voorbereiden
Als je dedatabase-driver gebruikt, heb je een tabel nodig om jobs in op te slaan.
Nieuwe projecten vanaf Laravel 11 bevatten de migration standaard,
maar als die ontbreekt maak je hem aan met de volgende commando’s.
De Redis-driver voorbereiden
Gebruik je deredis-driver, voeg dan een Redis-verbindingsconfiguratie toe aan config/database.php
en installeer de driver via Composer.
SQS Overflow Storage
Amazon SQS heeft een limiet op de maximale grootte van message payloads. Werk je met jobs waarvan de payload groot kan worden, voeg dan een configuratie toe die het overschot in een cache store opslaat en alleen een pointer naar SQS stuurt.- Als je
enabledaanzet, worden payloads van 1 MB of groter opgeslagen in de opgegeven cache store. - Zet je
alwaysoptrue, dan worden alle SQS-payloads ongeacht hun grootte in de cache store opgeslagen. delete_after_processingverwijdert de opgeslagen payload nadat de job geslaagd is (standaardtrue).- Zet je
flush_on_clearoptrue, dan wordt bij het uitvoeren vanqueue:cleareenflushgedaan op de overflow-store. Gebruik dit in combinatie met een aparte store, zodat je de reguliere cache niet wist.
Een jobklasse maken
Het make:job commando
Met het Artisan-commandomake:job genereer je een sjabloon voor een jobklasse.
app/Jobs/SendWelcomeEmail.php wordt gegenereerd.
Structuur van een jobklasse
ShouldQueue te implementeren laat je Laravel weten dat deze job asynchroon via de queue verwerkt moet worden.
De trait Queueable levert de methoden die nodig zijn voor de queue-bewerkingen van de job.
Jobs dispatchen
dispatch()
Om een job vanuit een controller of service naar de queue te sturen gebruik jedispatch().
Vertraagd dispatchen
Met de methodedelay() kun je de uitvoering van een job een opgegeven tijd uitstellen.
dispatchAfterResponse()
MetdispatchAfterResponse() wordt de job direct nadat de HTTP-response naar de gebruiker is teruggestuurd uitgevoerd.
Dit werkt ook met de sync-driver en is daarom geschikt voor lichte taken waarvoor geen aparte worker nodig is.
Dispatchen naar een specifieke queue
Queue Routing
Om een specifieke jobklasse standaard naar een vaste verbinding en queue te routeren, gebruik jeQueue::route() in de boot() van een ServiceProvider. Zo beheer je alles centraal in plaats van per jobklasse onQueue() / onConnection() te schrijven.
Queue Routing kan worden overschreven met
onQueue() / onConnection() op de job zelf.Queues doorsturen (Queue::forward())
Met Queue::forward() kun je jobs van de ene queue doorsturen naar een andere queue of verbinding. Handig als je de queue-infrastructuur wilt wisselen zonder de individuele jobs of de aanroepende code aan te passen.
Als de job zelf expliciet een verbinding opgeeft, heeft de instelling van de job voorrang op de doorstuurconfiguratie.
Synchroon uitvoeren (voor testen en ontwikkeling)
MetdispatchSync() voer je een job direct uit zonder de queue te gebruiken.
Bulk dispatchen
Als je een groot aantal onafhankelijke jobs in één keer wilt dispatchen, kun je de methodebulk() van de Bus-facade gebruiken. Ideaal voor gevallen waarin je geen tracking of callbacks zoals bij batchverwerking nodig hebt.
Bus::bulk() groepeert jobs op de geconfigureerde queue-verbinding en queuenaam en pusht elke groep in één keer naar de queue, wat efficiënt is.
Bus::bulk() verstuurt jobs gebundeld naar de queue. Anders dan bij batchverwerking (Bus::batch()) krijg je geen voortgangstracking of voltooiingscallbacks. Het is geschikt als je een grote hoeveelheid onafhankelijke jobs simpelweg in één keer wilt versturen.Job chains
Door jobs te chainen kun je meerdere jobs na elkaar uitvoeren. Als een job in de chain mislukt, worden de volgende jobs niet uitgevoerd.Job batches
Met batches kun je meerdere jobs gebundeld dispatchen en de totale voortgang volgen. Maak eerst een migration voor de tabeljob_batches.
Batchable in je jobklasse.
Bus::batch() dispatch je een batch en kun je callbacks registreren voor voltooiing, mislukking en afronding.
Jobs verwerken
Het queue:work commando
Start een queue-worker om jobs te verwerken.Opties voor het beheren van queue-workers
Door veelgebruikte opties te combineren kun je de worker nauwkeurig aansturen.Retry-instellingen in de jobklasse zetten
Soms is het overzichtelijker om de instellingen in de jobklasse zelf te zetten in plaats van via commandolijnopties.Jobs releasen (Release middleware)
Wil je een job onder bepaalde voorwaarden niet uitvoeren maar terugzetten op de queue, dan schrijf je dat beknopt met deRelease-middleware.
Release::unless() releaset wanneer de voorwaarde false is.
Mislukte jobs afhandelen
De failed_jobs-tabel voorbereiden
Wanneer een job het maximale aantal pogingen overschrijdt, wordt hij vastgelegd in de tabelfailed_jobs.
Bestaat de tabel nog niet, maak hem dan aan met de volgende commando’s.
Opruimen bij mislukking
Definieer je een methodefailed() op de job, dan kun je daar de afhandeling na een mislukking beschrijven.
Retries stoppen op basis van exceptions
Bij bepaalde soorten exceptions wil je de job niet opnieuw laten proberen maar direct laten mislukken. Geef binnenwithExceptions() in bootstrap/app.php met dontRetry de betreffende exception classes op.
dontRetryWhen. Wanneer de closure true teruggeeft, wordt de job direct als mislukt gemarkeerd en niet opnieuw geprobeerd.
Overzicht van mislukte jobs bekijken
Mislukte jobs opnieuw proberen
Mislukte jobs verwijderen
Veelgebruikte queue-drivers
De database-driver
Een eenvoudige driver waarmee je zonder extra middleware aan de slag kunt. Jobs worden opgeslagen in de tabeljobs en workers pollen deze om ze te verwerken.
- Voordelen: eenvoudige setup, je kunt je bestaande RDBMS direct gebruiken
- Nadelen: hoge belasting op de database, dus minder geschikt voor grote aantallen jobs
De redis-driver
De snelle driver die in productieomgevingen het meest wordt gebruikt. Omdat hij in-memory werkt is de doorvoer hoger dan bij een database en kun je grote aantallen jobs verwerken.- Voordelen: snel, schaalbaar
- Nadelen: je hebt een Redis-server nodig
Productiegebruik met Supervisor
In productie heb je een mechanisme nodig dat hetqueue:work-proces automatisch herstart wanneer het om welke reden dan ook stopt.
Op Linux is het gebruikelijk om hiervoor Supervisor te gebruiken.
numprocs=2 start je twee workerprocessen parallel.
Herlaad Supervisor na het instellen.
Praktijkvoorbeeld: e-mails versturen via de queue
1
Maak een jobklasse
2
Implementeer de verwerking van de job
3
Dispatch vanuit de controller
4
Start de worker
Samenvatting
Wanneer je queues zou moeten gebruiken
Wanneer je queues zou moeten gebruiken
- E-mails en sms’jes versturen
- Afbeeldingen en video’s verkleinen of converteren
- Requests naar externe API’s
- Rapporten genereren of CSV-exports maken
- Webhooks versturen
Tips voor tijdens de ontwikkeling
Tips voor tijdens de ontwikkeling
Zet je in
.env QUEUE_CONNECTION=sync, dan worden jobs direct uitgevoerd zonder de queue te gebruiken.
Je kunt dan alles testen zonder een worker te starten, wat tijdens de ontwikkeling handig is.Overzicht van veelgebruikte commando's
Overzicht van veelgebruikte commando's