Background Processing với Laravel
php artisan make:job ProcessPodcast
php artisan make:job SendWelcomeEmail
<?php
// app/Jobs/SendWelcomeEmail.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 int $tries = 3; // Số lần retry
public int $backoff = 60; // Delay giữa các lần retry (giây)
public int $timeout = 120; // Timeout (giây)
public int $maxExceptions = 3; // Số exception tối đa
public function __construct(
public User $user
) {}
public function handle(): void
{
Mail::to($this->user->email)
->send(new WelcomeMail($this->user));
}
// Xử lý khi job fail
public function failed(\Throwable $exception): void
{
// Log hoặc notify admin
Log::error("Failed to send welcome email to {$this->user->email}", [
'exception' => $exception->getMessage()
]);
}
// Điều kiện retry
public function retryUntil(): DateTime
{
return now()->addHours(24);
}
}
// Dispatch job
SendWelcomeEmail::dispatch($user);
// Dispatch với delay
SendWelcomeEmail::dispatch($user)->delay(now()->addMinutes(10));
// Dispatch vào queue cụ thể
SendWelcomeEmail::dispatch($user)->onQueue('emails');
<?php
use Illuminate\Support\Facades\Bus;
// Jobs chạy tuần tự
Bus::chain([
new ProcessPodcast($podcast),
new OptimizeAudio($podcast),
new SendPodcastNotification($podcast),
])->dispatch();
// Chain với error handling
Bus::chain([
new ProcessOrder($order),
new SendInvoice($order),
new UpdateInventory($order),
])->catch(function (Throwable $e) {
// Xử lý khi có job trong chain fail
Log::error('Order processing failed', ['error' => $e->getMessage()]);
})->dispatch();
<?php
use Illuminate\Bus\Batch;
use Illuminate\Support\Facades\Bus;
use Throwable;
// Xử lý batch jobs song song
$batch = Bus::batch([
new ProcessImage($image1),
new ProcessImage($image2),
new ProcessImage($image3),
])->then(function (Batch $batch) {
// Tất cả jobs hoàn thành
Log::info("Batch {$batch->id} completed!");
})->catch(function (Batch $batch, Throwable $e) {
// Có job fail
})->finally(function (Batch $batch) {
// Batch kết thúc (dù thành công hay fail)
})->name('Image Processing')
->allowFailures()
->dispatch();
// Kiểm tra batch status
$batch = Bus::findBatch($batchId);
echo $batch->progress(); // % hoàn thành
echo $batch->pendingJobs;
echo $batch->failedJobs;
composer require laravel/horizon
php artisan horizon:install
# Chạy Horizon
php artisan horizon
<?php
// config/horizon.php
'environments' => [
'production' => [
'supervisor-1' => [
'maxProcesses' => 10,
'balanceMaxShift' => 1,
'balanceCooldown' => 3,
],
],
'local' => [
'supervisor-1' => [
'maxProcesses' => 3,
],
],
],
/horizon.