0%

Laravel 使用 Redis queue 時發生 Max Attempts Exceeded Exception 的解法紀錄

前言

專案將 Laravel 的 QUEUE_CONNECTIONdatabase 切換到 redis,並透過 Supervisor 背景執行 queue worker。初始設定中,Redis driver 預設 retry_after 為 90 秒,導致工作常在執行 90 秒後被重新派發,並因多次重試而拋出 MaxAttemptsExceededException
log大致如下:

1
production.ERROR: App\Jobs\getApiCargoFormApiCompanion has been attempted too many times or run too long. The job may have previously timed out.

以下整理兩種解法。

解法步驟(擇一)

選項一:修改 config/queue.php

1
2
3
4
5
6
7
8
9
10
'connections' => [
// …
'redis' => [
'driver' => 'redis',
'connection' => 'default',
'queue' => env('REDIS_QUEUE', 'default'),
'retry_after' => env('REDIS_RETRY_AFTER', 600),
'block_for' => null,
],
],

.env:

1
REDIS_RETRY_AFTER=600

更新設定:

1
2
php artisan config:clear
php artisan config:cache

選項二:使用 Supervisor 自訂參數

在任何啟動 queue worker 的指令後,加上 --retry-after 參數即可。範例:

1
php artisan queue:work redis --retry-after=600

結果與小結

經過上述任一調整後,所有 Job 已能正常執行超過 90 秒而不中斷,並順利完成處理,MaxAttemptsExceededException 不再發生。
提醒:務必確保 retry_after 的值與 --timeout 或 Worker 執行時間需求一致,避免 Redis 判定工作「卡住」而過早重試。