aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Webontwikkeling

Laravel Queue en Jobs: gids voor achtergrondtaken

Een Laravel queue laat je traag werk — een welkomstmail versturen, een afbeelding verwerken, een externe API aanroepen — uit de request-responscyclus halen en naar de achtergrond verplaatsen. De gebruiker wacht niet langer tot de e-mail daadwerkelijk verstuurd is; de taak wordt op een wachtrij gezet en later afgehandeld door een worker op de achtergrond, wanneer hij aan de beurt is. In deze gids zetten we de wachtrij-infrastructuur vanaf nul op, schrijven we onze eigen jobklasse, draaien we de worker en handelen we fouten robuust af.

Waarom heb je een wachtrij nodig?

In een synchrone applicatie gebeurt alles binnen dezelfde request. De gebruiker verstuurt het registratieformulier, jij stuurt de mail, schaalt misschien een afbeelding, en pas daarna keert de response terug naar de browser. Als de mailserver traag is, wacht de gebruiker seconden. Een wachtrij scheidt deze taken:

  • Snelheid: traag werk gaat naar de achtergrond en de response keert direct terug.
  • Veerkracht: als een job mislukt, kan hij automatisch opnieuw geprobeerd worden.
  • Schaalbaarheid: je kunt meerdere workers draaien en de belasting verdelen.

Een queue-driver kiezen

Laravel ondersteunt meerdere queue-drivers, allemaal achter één API. Je kiest er een met de variabele QUEUE_CONNECTION in je .env-bestand:

QUEUE_CONNECTION=database

De gangbare opties zijn:

  • sync — de standaard; de job draait direct binnen dezelfde request. Buiten lokale ontwikkeling nutteloos.
  • database — bewaart jobs in een databasetabel. Eenvoudig op te zetten, ruim voldoende voor kleine/middelgrote projecten.
  • redis — de snelle, aanbevolen keuze voor hoog volume.
  • sqs — een beheerde, serverless wachtrij via Amazon SQS.

Gebruik je de database-driver, dan heb je een tabel nodig voor de wachtrij. Laravel levert een commando om die te genereren:

php artisan make:queue-table
php artisan migrate

Je eerste jobklasse maken

Een job is één eenheid werk die op de wachtrij draait. Maak er een met artisan:

php artisan make:job SendWelcomeEmail

Dit genereert app/Jobs/SendWelcomeEmail.php. Een klasse die de interface ShouldQueue implementeert, wordt automatisch in de wachtrij gezet. De methode handle() bevat de eigenlijke logica van het werk:

<?php

namespace App\Jobs;

use App\Models\User;
use App\Mail\WelcomeMail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Mail;

class SendWelcomeEmail implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public function __construct(public User $user) {}

    public function handle(): void
    {
        Mail::to($this->user)->send(new WelcomeMail($this->user));
    }
}

Let op één ding: we geven een User-model door aan de constructor. Dankzij de trait SerializesModels wordt alleen de primaire sleutel geserialiseerd in plaats van het hele model; wanneer de job draait, wordt het model vers opnieuw uit de database geladen.

De job in de wachtrij plaatsen (dispatch)

Om de job te starten gebruik je dispatch. De eenvoudigste vorm is de statische methode:

use App\Jobs\SendWelcomeEmail;

SendWelcomeEmail::dispatch($user);

Met vloeiende, geketende methoden stel je in hoe de job draait:

SendWelcomeEmail::dispatch($user)
    ->onQueue('emails')        // naar een specifieke wachtrij
    ->delay(now()->addMinutes(5)); // met 5 minuten vertraging

Om meerdere jobs achter elkaar te draaien gebruik je Bus::chain(), en voor parallelle groepen Bus::batch(). Klein beginnen is prima; je voegt deze functies toe zodra je ze nodig hebt.

De worker draaien

Jobs belanden op de wachtrij, maar er is een proces nodig om ze af te handelen. Daarvoor dient de worker:

php artisan queue:work

Dit commando draait continu en wacht op nieuwe jobs. Een paar belangrijke vlaggen:

  • --queue=emails,default — luistert naar wachtrijen op volgorde van prioriteit.
  • --tries=3 — hoe vaak een job wordt geprobeerd als hij mislukt.
  • --timeout=60 — hoeveel seconden één job maximaal mag duren.

Een cruciaal punt: queue:work laadt je applicatie in het geheugen. Wanneer je de code wijzigt, blijft de worker de oude versie draaien. Daarom moet je de worker na elke deploy herstarten:

php artisan queue:restart

Gebruik in productie een procesmanager zoals Supervisor, zodat de worker weer opstart, zelfs als hij crasht. Supervisor bewaakt het queue:work-proces en herstart het automatisch wanneer nodig.

Mislukte jobs afhandelen

Jobs mislukken soms: de mailserver reageert niet, een API loopt af in een time-out. Als alle pogingen op zijn, registreert Laravel de job in de tabel failed_jobs. Maak de bijbehorende migratie aan:

php artisan make:queue-failed-table
php artisan migrate

Je kunt mislukte jobs tonen en opnieuw proberen:

php artisan queue:failed       # tonen
php artisan queue:retry all    # alles opnieuw proberen
php artisan queue:flush        # alles verwijderen

Voeg je een failed()-methode toe aan je jobklasse, dan draait die wanneer de job definitief mislukt; daar kun je een beheerder waarschuwen of een log wegschrijven. Je kunt ook de eigenschap $backoff gebruiken om een wachttijd tussen pogingen in te stellen — cruciaal om een wankele service tijdens tijdelijke storingen niet te overspoelen.

Veelgestelde vragen

Hoe kies ik tussen de database- en redis-driver?

Tot een paar duizend jobs per dag is database prima en heeft het geen extra infrastructuur nodig. Stap over op Redis als je hoog volume, lage latentie of geavanceerde functies zoals Bus::batch() nodig hebt. De meeste projecten beginnen met database en migreren zodra de behoefte ontstaat.

Waarom moet ik de worker na een codewijziging herstarten?

Omdat queue:work een langlevend proces is dat de applicatie eenmalig in het geheugen laadt. Code die je wijzigt, wordt niet weerspiegeld in de kopie in het geheugen. php artisan queue:restart laat de huidige jobs aflopen en zegt de worker veilig te herstarten.

Hoe lang mag een job draaien?

Dat stel je in met de vlag --timeout (standaard 60 seconden). Verhoog de waarde voor langere jobs, maar zorg dat de timeout korter is dan de instelling retry_after van de wachtrij; anders kan dezelfde job tweemaal verwerkt worden.

Wil je je wachtrij aan de praat krijgen, dan kunnen we samen de trage plekken in je project opsporen en naar de achtergrond verplaatsen; neem contact met me op om je Laravel-infrastructuur op te zetten of te optimaliseren.

Devamı için