Ontwerp een Geavanceerde Laravel Queue en Job Workflow voor Taakverdeling
description
Met deze prompt kan de gebruiker een krachtige en flexibele taakverdelingsworkflow opzetten die zorgt voor efficiënte verwerking van achtergrondtaken met prioriteitsbeheer en foutafhandeling. Dit helpt om de prestaties en betrouwbaarheid van Laravel-applicaties te verbeteren, wat beter is dan eenvoudige standaardqueue-oplossingen zonder prioriteiten of geavanceerde controles.
prompt
Help mij een geavanceerde queue- en jobworkflow in mijn Laravel applicatie te ontwerpen. Ik wil dat mijn taken efficiënt worden verdeeld en uitgevoerd, met prioriteitsinstellingen en foutafhandeling. Geef aan welke taken je wilt verwerken: <beschrijf de taken die je wil ...
try_prompt
generate_helper
disclaimerOnPageApi
tags
ai_answers
provider: openai
model: gpt-4.1-nano
Natuurlijk! Hier is een gedetailleerd ontwerp voor een geavanceerde queue- en jobworkflow in jouw Laravel applicatie, inclusief prioriteitsbeheer, foutafhandeling en configuratie van verschillende queue-verbindingen.
---
### 1. Taken en Prioriteiten
**Taken:**
- E-mails verzenden
- Rapporten genereren
**Prioritering:**
- **Hoog:** E-mails verzenden (kritisch voor communicatie en klantenservice)
- **Laag:** Rapporten genereren (niet direct kritisch, kan achteraan worden gedaan)
---
### 2. Implementatie van Prioriteit in Laravel
Laravel ondersteunt standaard geen prioriteiten binnen één queue, maar je kunt dit realiseren door verschillende queues te gebruiken of door een prioriteitsbeoordeling in je jobs.
**Optie A: Meerdere queues per prioriteit**
Definieer verschillende queues in `config/queue.php`:
```php
'connections' => [
'redis' => [
'driver' => 'redis',
'queue' => env('REDIS_QUEUE', 'default'),
'retry_after' => 90,
],
// andere verbindingen
],
```
Gebruik verschillende queue-namen voor prioriteiten:
```php
// Voor hoge prioriteit
dispatch((new SendEmailsJob())->onQueue('high'));
// Voor lage prioriteit
dispatch((new GenerateReportsJob())->onQueue('low'));
```
**Optie B: Prioriteit binnen één queue via job-structuur**
Gebruik een `priority` property in je job en een custom worker die deze prioriteit leest en de jobs in de juiste volgorde verwerkt.
---
### 3. Foutafhandeling en Retry Strategie
Gebruik Laravel's ingebouwde retry-mechanismen voor jobs:
```php
class SendEmailsJob implements ShouldQueue
{
public $tries = 3; // Max 3 retries
public $retryAfter = 60; // Wacht 60 seconden tussen retries
public function handle()
{
// E-mail verzendlogica
}
public function failed(Exception $exception)
{
// Notificatie bij mislukking
Mail::to('admin@jouwdomein.nl')->send(new JobFailedNotification('E-mails verzenden faalde', $exception));
}
}
```
Voor rapporten: zelfde aanpak, maar met lagere prioriteit.
---
### 4. E-mail notificaties bij foutmeldingen
Maak een Mailable:
```php
class JobFailedNotification extends Mailable
{
public $message;
public $exception;
public function __construct($message, $exception)
{
$this->message = $message;
$this->exception = $exception;
}
public function build()
{
return $this->subject('Job Foutmelding')
->view('emails.job_failed');
}
}
```
---
### 5. Configuratie van verschillende queue-verbindingen
Laravel ondersteunt meerdere connecties zoals `sync`, `redis`, `beanstalkd`, `sqs`, etc.
**Voor optimale prestaties:**
- Gebruik Redis voor high throughput en lage latency.
- Split verschillende taken over verschillende verbindingen of queues.
- Bijvoorbeeld:
```php
// In config/queue.php
'connections' => [
'redis_high' => [
'driver' => 'redis',
'queue' => 'high_priority',
'retry_after' => 60,
],
'redis_low' => [
'driver' => 'redis',
'queue' => 'low_priority',
'retry_after' => 300,
],
],
```
**Worker starten voor verschillende queues:**
```bash
php artisan queue:work redis_high --queue=high_priority --tries=3
php artisan queue:work redis_low --queue=low_priority --tries=3
```
Zo kun je resources optimaal inzetten en prioriteiten respecteren.
---
### Samenvatting
- **Prioriteiten:** gescheiden queues of interne prioriteitslogica
- **Foutafhandeling:** maximaal 3 retries, notificatie bij falen
- **Prestaties:** meerdere queue-verbindingen en gescheiden workers
Als je verdere specificaties of hulp nodig hebt bij het coderen, laat het weten!
provider: deepseek
model: deepseek-chat
Absoluut. Hier is een gedetailleerd ontwerp voor een geavanceerde queue- en jobworkflow in Laravel, specifiek toegespitst op jouw vereisten.
---
### 1. Job Classes Aanmaken
Eerst maken we dedicated job classes voor elke taak. Dit zorgt voor propere code-opsplitsing en onderhoud.
**a. Job: SendEmailJob**
```php
// app/Jobs/SendEmailJob.php
namespace App\Jobs;
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;
use App\Mail\YourMailableClass;
use Illuminate\Support\Facades\Log;
class SendEmailJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $tries = 3; // Max 3 retries
public $maxExceptions = 3; // Max 3 failed attempts
public $backoff = [60, 180, 300]; // Wacht 60, 180, dan 300 sec tussen retries
protected $emailData;
/**
* Create a new job instance.
*/
public function __construct($emailData)
{
$this->emailData = $emailData;
// STANDAARD PRIORITEIT: high (voor e-mails)
$this->onQueue('high');
}
/**
* Execute the job.
*/
public function handle(): void
{
Mail::to($this->emailData['to'])
->send(new YourMailableClass($this->emailData));
}
/**
* Handle a job failure.
*/
public function failed(\Throwable $exception): void
{
// Log de fout
Log::error('E-mail job mislukt: ' . $exception->getMessage(), ['emailData' => $this->emailData]);
// Stuur een notificatie naar de beheerder
// Zorg dat je een Notification class hebt, bv. JobFailedNotification
// \App\Models\User::find(1)->notify(new JobFailedNotification($this, $exception));
}
}
```
**b. Job: GenerateReportJob**
```php
// app/Jobs/GenerateReportJob.php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use PDF; // Of een andere library voor rapporten
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
class GenerateReportJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $tries = 3;
public $maxExceptions = 3;
public $backoff = [120, 300]; // Langer wachten voor rapporten
protected $reportParameters;
/**
* Create a new job instance.
*/
public function __construct($reportParameters)
{
$this->reportParameters = $reportParameters;
// STANDAARD PRIORITEIT: low (voor rapporten)
$this->onQueue('low');
}
/**
* Execute the job.
*/
public function handle(): void
{
// Genereer het rapport (voorbeeld met PDF)
$pdf = PDF::loadView('reports.template', $this->reportParameters);
$fileName = 'report_' . time() . '.pdf';
// Sla het op of stuur het naar een storage disk
Storage::disk('s3')->put('reports/' . $fileName, $pdf->output());
// Of sla lokaal op: $pdf->save(storage_path('app/reports/' . $fileName));
// Update database status etc. (indien nodig)
}
/**
* Handle a job failure.
*/
public function failed(\Throwable $exception): void
{
Log::error('Rapport generatie job mislukt: ' . $exception->getMessage(), ['parameters' => $this->reportParameters]);
// Stuur notificatie naar beheerder
}
}
```
---
### 2. Prioriteiten Instellen (Queue Strategy)
Je specificeerde: **E-mails hebben hoge prioriteit, rapporten hebben lage prioriteit.**
We implementeren dit door jobs naar verschillende **queues** te sturen. In de job classes hierboven zie je al `$this->onQueue('high');` en `$this->onQueue('low');`.
**Hoe je een job met een specifieke prioriteit dispatcht:**
```php
// Voor een hoge-prioriteit e-mail
SendEmailJob::dispatch($emailData)->onQueue('high');
// Voor een laag-prioriteit rapport
GenerateReportJob::dispatch($reportData)->onQueue('low');
```
---
### 3. Foutafhandeling Strategy
Je vereiste: **Max 3 retries met e-mailnotificatie bij falen.**
Dit is afgehandeld in de job classes:
* `public $tries = 3;`: Definieert het maximum aantal pogingen.
* `public $backoff = [];`: Definieert de wachttijden (in seconden) tussen pogingen. E-mails herproberen we sneller.
* De `failed(\Throwable $exception)` methode: Wordt automatisch aangeroepen na de laatste mislukte poging. Hier loggen we de fout en **sturen we de e-mailnotificatie** naar een beheerder.
**Stap om de e-mailnotificatie te voltooien:**
1. Maak een Notification class aan: `php artisan make:notification JobFailedNotification`
2. Implementeer de logica in de `toMail` methode van die notification om de details van de mislukte job (`$this->job`) en de exception (`$this->exception`) door te sturen.
3. Decommentariseer en pas de regel in de `failed` methode van de job aan om deze notification te gebruiken.
---
### 4. Configuratie van Queue-verbindingen voor Optimale Prestaties
De kracht van Laravel komt tot uiting door meerdere queue "workers" te configureren die parallel verschillende queues afhandelen.
**a. .env Configuratie**
Kies een queue driver zoals Redis (`redis`) of Amazon SQS (`sqs`) voor productie. Database (`database`) is oké voor ontwikkeling.
```env
QUEUE_CONNECTION=redis
REDIS_CLIENT=predis # Of phpredis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
```
**b. config/queue.php Configuratie**
Definieer je connections en vooral de queues binnen de `redis` connection.
```php
'connections' => [
// ... andere connections ...
'redis' => [
'driver' => 'redis',
'connection' => 'default',
'queue' => env('REDIS_QUEUE', 'default'),
'retry_after' => 90, // Seconden. Hoger dan je langste job kan duren.
'block_for' => 5,
'after_commit' => false,
// QUEUES MET PRIORITEITEN DEFINIEREN
'queues' => [
'high', // Worker pakt eerst jobs van 'high'
'low', // Daarna pas van 'low'
],
],
],
```
**c. Workers Starten voor Optimale Prestaties**
Het geheim zit hem in het starten van **gespecialiseerde workers** voor elke queue. Open verschillende terminal tabs/schermen.
* **Worker voor HOGE prioriteit (E-mails):**
Deze worker luistert continu naar de `high` queue en pakt eventueel ook `low` jobs aan *als de high queue leeg is*.
```bash
php artisan queue:work redis --queue=high,low
```
* **Worker voor LAGE prioriteit (Rapporten):**
Deze worker is trager en luistert alleen naar de `low` queue. Je kunt meerdere instances van deze worker starten als je veel rapporten hebt.
```bash
php artisan queue:work redis --queue=low --timeout=600
# --timeout=600: Geef deze worker 10 minuten (600s) om 1 groot rapport af te maken.
```
* **Voor Ontwikkeling/Supervisie:**
```bash
# Algemene worker voor alle queues in volgorde van prioriteit
php artisan queue:work redis --queue=high,low
```
**d. Supervisor Configuratie (Voor Productie)**
Voor productie gebruik je Supervisor om je worker processen altijd draaiende te houden. Configuratiebestand (`/etc/supervisor/conf.d/laravel-worker.conf`):
```ini
; High Priority Worker - voor e-mails
[program:laravel-worker-high]
process_name=%(program_name)s_%(process_num)02d
command=php /home/forge/je-app.nl/artisan queue:work redis --queue=high,low --sleep=3 --max-jobs=1000 --max-time=3600
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=forge
numprocs=2 ; Start 2 processen voor parallellisme
redirect_stderr=true
stdout_logfile=/home/forge/je-app.nl/worker-high.log
; Low Priority Worker - voor rapporten
[program:laravel-worker-low]
process_name=%(program_name)s_%(process_num)02d
command=php /home/forge/je-app.nl/artisan queue:work redis --queue=low --sleep=10 --timeout=600
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=forge
numprocs=1 ; Minder processen voor resource-intensieve taken
redirect_stderr=true
stdout_logfile=/home/forge/je-app.nl/worker-low.log
```
Na configuratie, run:
```bash
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start laravel-worker-high:*
sudo supervisorctl start laravel-worker-low:*
```
### Samenvatting
1. **Jobs**: Maak dedicated jobs (`SendEmailJob`, `GenerateReportJob`) met `$tries`, `$backoff`, en een `failed()` methode.
2. **Prioriteit**: Stel in via `->onQueue('high')` of `->onQueue('low')` bij het dispatchen.
3. **Foutafhandeling**: Laravel's built-in retry mechanisme + een e-mailnotificatie in de `failed()` methode.
4. **Performantie**: Gebruik Redis als driver en start meerdere, gespecialiseerde worker processen (bijv. met Supervisor) die parallel de `high` en `low` queues afhandelen volgens de gewenste prioriteit.
Dit ontwerp zorgt voor een robuust, schaalbaar en efficiënt queuesysteem in je Laravel applicatie.