Laravel Queues 任務佇列

config/queue.php 配置說明

Laravel 支援多種佇列驅動,包括:

  • database:使用資料庫儲存任務
  • beanstalkd:輕量級佇列系統
  • redis:快速且適合高併發的佇列
  • sqs:Amazon Simple Queue Service
  • sync:本機同步執行(適用於本地測試)

1. 使用 database 佇列

建立任務用的 jobs 資料表:

php artisan queue:table
php artisan migrate

2. 安裝相依套件(依使用的驅動)

驅動 相依套件
Amazon SQS aws/aws-sdk-php
Beanstalkd pda/pheanstalk
Redis predis/predis(可選)或使用原生 PhpRedis

Laravel 9+ 預設已支援 PhpRedis,可不用安裝 predis。

3. database 驅動設定範例

return [
    'default' => env('QUEUE_CONNECTION', 'database'),

    'connections' => [
        'database' => [
            'driver' => 'database',
            'table' => 'jobs',
            'queue' => 'default',
            'retry_after' => 60,
            'tries' => 3,
        ],
    ],
];

啟動佇列監聽

使用 queue:listen(程式碼更新不需重啟)

php artisan queue:listen
php artisan queue:listen database

使用 queue:work(效能較佳,更新程式需 queue:restart)

php artisan queue:work database --daemon
php artisan queue:restart

建立任務(Job)

使用 make:job 指令建立任務類別:

php artisan make:job SendReminderEmail --queued

產生的任務類別會預設放在 app/Jobs 目錄,並自動實作 ShouldQueue 介面。

任務類別範例

<?php

namespace App\Jobs;

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

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

    protected $user;

    /**
     * 建構子,注入使用者資料。
     */
    public function __construct(User $user)
    {
        $this->user = $user;
    }

    /**
     * 任務執行邏輯。
     */
    public function handle(): void
    {
        Mail::send('emails.reminder', ['user' => $this->user], function ($message) {
            // 設定收件者等參數
        });

        $this->user->reminders()->create([
            // 建立提醒紀錄
        ]);
    }
}

其他補充

  • 延遲執行任務(秒)
SendReminderEmail::dispatch($user)->delay(now()->addSeconds(10));
  • 釋放任務延遲後再試
if ($condition) {
    $this->release(10); // 10 秒後再重新加入佇列
}
  • 檢查重試次數
if ($this->attempts() > 3) {
    // 超過重試次數,可記錄錯誤或丟入失敗佇列
}

推送任務至佇列

use App\Jobs\SendReminderEmail;
use App\Models\User;

$user = User::findOrFail($id);
SendReminderEmail::dispatch($user);

補充

  • Laravel 5.1 開始,SelfHandling 介面已廢除,不需再實作。
  • Laravel 建議使用 queue:work 搭配 process manager(如 Supervisor)部署於正式環境。
  • 使用 php artisan queue:failed 可查看失敗任務,queue:retry 可重試失敗任務。