PHP项目Laravel队列任务超时时间

wen PHP项目 4

本文目录导读:

PHP项目Laravel队列任务超时时间

  1. 在任务类中定义 $timeout 属性
  2. 在队列监听器/Work 命令中设置
  3. 持久化配置(推荐)
  4. 通过队列名称或连接指定超时
  5. 使用 failed 方法处理超时任务
  6. 高级配置:按队列设置不同的超时时间
  7. 重试次数的设置
  8. 重要提醒:

在 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]; // 重试间隔(秒)
}

重要提醒:

  1. timeout vs retry_after

    • timeout:任务执行的最大时间,超时后会被终止
    • retry_after:任务失败后,多长时间可以重新进入队列
  2. timeoutretry_after 的关系

    • 通常设置 retry_after 略大于 timeout,防止任务被重复执行
    • timeout=60, retry_after=90
  3. 性能考虑

    • PHP 默认有 max_execution_time 限制,通常为 30 秒
    • 如果任务超过 30 秒,需要确保 PHP CLI 配置不受限制
  4. 监控超时任务

    # 查看失败的队列任务
    php artisan queue:failed

通过合理配置这些参数,可以更好地控制队列任务的执行时间和资源使用。

抱歉,评论功能暂时关闭!