插件窝 干货文章 Laravel 8.x队列任务失败如何避免日志记录并实现延迟重试?

Laravel 8.x队列任务失败如何避免日志记录并实现延迟重试?

Illuminate 任务 failed 方法 697    来源:    2025-03-14

在 Laravel 8.x 中,队列任务失败时默认会记录日志。如果你希望避免日志记录并实现延迟重试,可以通过以下方式来实现:

1. 避免日志记录

要避免队列任务失败时记录日志,你可以在任务类中重写 failed 方法,并在其中不调用父类的 failed 方法。这样,任务失败时不会记录日志。

<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

class ExampleJob implements ShouldQueue
{
    use InteractsWithQueue, Queueable, SerializesModels;

    public function handle()
    {
        // 任务处理逻辑
    }

    public function failed(\Throwable $exception)
    {
        // 不调用父类的 failed 方法,避免日志记录
        // parent::failed($exception);
    }
}

2. 实现延迟重试

Laravel 提供了内置的延迟重试机制。你可以在任务类中设置 $tries$backoff 属性来控制重试次数和重试延迟。

  • $tries 属性用于设置任务的最大重试次数。
  • $backoff 属性用于设置每次重试的延迟时间(以秒为单位)。
<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

class ExampleJob implements ShouldQueue
{
    use InteractsWithQueue, Queueable, SerializesModels;

    // 最大重试次数
    public $tries = 3;

    // 重试延迟时间(秒)
    public $backoff = [60, 120, 240];

    public function handle()
    {
        // 任务处理逻辑
    }

    public function failed(\Throwable $exception)
    {
        // 不调用父类的 failed 方法,避免日志记录
        // parent::failed($exception);
    }
}

在上面的例子中,任务将在第一次失败后等待 60 秒重试,第二次失败后等待 120 秒重试,第三次失败后等待 240 秒重试。

3. 使用 retryUntil 方法

你还可以使用 retryUntil 方法来设置任务的最大重试时间。该方法返回一个 DateTime 对象,表示任务的最大重试时间。

<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Carbon\Carbon;

class ExampleJob implements ShouldQueue
{
    use InteractsWithQueue, Queueable, SerializesModels;

    public function handle()
    {
        // 任务处理逻辑
    }

    public function retryUntil()
    {
        return Carbon::now()->addMinutes(10); // 任务将在 10 分钟后不再重试
    }

    public function failed(\Throwable $exception)
    {
        // 不调用父类的 failed 方法,避免日志记录
        // parent::failed($exception);
    }
}

总结

通过重写 failed 方法并避免调用父类的 failed 方法,你可以避免队列任务失败时记录日志。同时,通过设置 $tries$backoff 属性或使用 retryUntil 方法,你可以实现延迟重试机制。