0

这是对 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 尝试次数过多或运行时间过长。该作业之前可能已超时。

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

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

4

2 回答 2

2

Laravel 文档对此有提示:

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

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

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

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

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

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

于 2018-10-26T18:40:19.710 回答
1

[...] has been attempted too many times or run too long是一个错误,它不会告诉您作业失败的原因。这意味着其他一些异常导致您的工作在每次工作人员尝试时都失败,并且工作人员已经尝试了您的配置允许的最大次数。要了解它失败的原因,请检查您的 laravel.log 文件以了解导致作业失败的异常。

在您的情况下,由于Mailer正在联系外部系统,因此您连接的系统可能会限制您的速率,或者他们可能存在临时连接问题或其他服务停机时间。同样,您的日志文件中应该有更多详细信息。

于 2018-10-26T18:31:51.280 回答