本文目录导读:

- 在任务类中定义
$timeout属性 - 在队列监听器/Work 命令中设置
- 持久化配置(推荐)
- 通过队列名称或连接指定超时
- 使用
failed方法处理超时任务 - 高级配置:按队列设置不同的超时时间
- 重试次数的设置
- 重要提醒:
在 Laravel 中,队列任务的超时时间可以通过以下几种方式设置:
在任务类中定义 $timeout 属性
<?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;
class ProcessPodcast implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* 任务超时时间(秒)
*
* @var int
*/
public $timeout = 120; // 2分钟
/**
* Execute the job.
*/
public function handle(): void
{
// 处理任务
}
}
在队列监听器/Work 命令中设置
使用 Artisan 命令时:
# 设置超时时间为 300 秒 php artisan queue:work --timeout=300 # 或者使用队列监听器 php artisan queue:listen --timeout=300
在 RegisterServiceProvider 中设置:
// app/Providers/AppServiceProvider.php
public function boot()
{
$this->app->bind('queue.worker', function ($app) {
return new Worker(
$app['queue'],
$app['events'],
$app['cache'],
function () use ($app) {
return $app->config->get('queue.worker_timeout', 60);
}
);
});
}
持久化配置(推荐)
在 .env 文件中添加:
QUEUE_TIMEOUT=300
然后在 config/queue.php 中引用:
'default' => env('QUEUE_CONNECTION', 'database'),
// 在 connections 数组中为每个连接添加 timeout
'connections' => [
'database' => [
'driver' => 'database',
'table' => 'jobs',
'queue' => 'default',
'retry_after' => 90, // 任务超时后重试的时间
'timeout' => env('QUEUE_TIMEOUT', 60), // 任务超时时间
],
'redis' => [
'driver' => 'redis',
'connection' => 'default',
'queue' => 'default',
'retry_after' => 90,
'timeout' => env('QUEUE_TIMEOUT', 60),
'block_for' => null,
],
],
通过队列名称或连接指定超时
// 在任务类中动态设置超时时间
class ProcessPodcast implements ShouldQueue
{
public $timeout;
public function __construct()
{
// 根据业务逻辑动态设置超时时间
$this->timeout = 60; // 默认60秒
// 或者根据任务类型
$this->timeout = $this->isLargeFile() ? 300 : 60;
}
}
使用 failed 方法处理超时任务
public function failed(\Throwable $exception)
{
// 任务失败时的处理
Log::error('Job failed: ' . $exception->getMessage());
}
高级配置:按队列设置不同的超时时间
在 AppServiceProvider.php 中:
use Illuminate\Queue\Events\JobProcessing;
public function boot()
{
$this->app['events']->listen(JobProcessing::class, function ($event) {
// 根据队列名称动态调整超时时间
if ($event->connectionName === 'redis' && $event->job->getQueue() === 'high_priority') {
$event->job->getCapsule()->getContainer()->make('queue.worker')
->setTimeout(300);
}
});
}
重试次数的设置
class ProcessPodcast implements ShouldQueue
{
public $tries = 3; // 最多尝试3次
public function retryUntil()
{
return now()->addMinutes(5); // 5分钟内重试
}
public $backoff = [60, 120, 300]; // 重试间隔(秒)
}
重要提醒:
-
timeoutvsretry_after:timeout:任务执行的最大时间,超时后会被终止retry_after:任务失败后,多长时间可以重新进入队列
-
timeout与retry_after的关系:- 通常设置
retry_after略大于timeout,防止任务被重复执行 timeout=60, retry_after=90
- 通常设置
-
性能考虑:
- PHP 默认有
max_execution_time限制,通常为 30 秒 - 如果任务超过 30 秒,需要确保 PHP CLI 配置不受限制
- PHP 默认有
-
监控超时任务:
# 查看失败的队列任务 php artisan queue:failed
通过合理配置这些参数,可以更好地控制队列任务的执行时间和资源使用。