首页 > 解决方案 > 作业总是在 laravel 作业中失败 Redis 速率限制

问题描述

这是对 Laravel 的后续 - 按顺序运行作业

我决定使用 redis 速率限制。代码如下

jobClass {

  protected $subscription;

  public function __construct(Subscription$subscription) {
        $this->subscription= $subscription;
    }
  public function handle() {
    Redis::funnel('mailingJob')->limit(1)->then(function () {
            // Job logic...
            (new Mailer($this->subscription))->send();

        }, function () {
            // Could not obtain lock...
            return $this->release(10);
        });
  }
}

控制器代码看起来像。

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Models\Subscriptions;
class MailController extends Controller
{


    public function sendEmail() {
        Subscriptions::all()
        ->each(function($subscription) {
            SendMailJob::dispatch($subscription);
        });
    }
}

现在,当我运行队列时,其中一些工作休息(大约 90%)失败,出现以下错误。

SendMailJob 尝试次数过多或运行时间过长。该作业之前可能已超时。

我错过了什么?请有人引导我走向正确的方向。

我的目标是一次只运行一个类型的作业。

标签: laravelredislaravel-5.6laravel-horizon

解决方案


Laravel 文档对此有提示:

使用速率限制时,您的作业需要成功运行的尝试次数可能很难确定。因此,将速率限制与基于时间的尝试结合起来很有用。

问题的核心是,作业一直失败,直到它可以实现锁定并运行。

所以我想在你运行队列工作者的地方,你没有将--tries标志设置得足够高。

尽管您可以设置一个非常高的--tries,但它并不是真正可扩展的。

如文档中所建议的,最好的解决方案是增加尝试次数以及使用基于时间的尝试

您也可以return $this->release(10);在此处增加发布时间。这应该让作业在尝试重新获取锁之前等待更长的时间,因此将使用更少的尝试!


推荐阅读