Laravel 排队的作业 运行 比超时时间长很多分钟

Laravel Queued Jobs Running for Many Minutes Longer Than Timeout

我有一个 Laravel 排队作业,它从网页中提取 links。通过 Laravel Forge 配置的队列侦听器的超时为 240 秒(4 分钟)。但是,作业最多需要 45 分钟 到 运行。

我的队列设置是:

'redis' => [
    'driver' => 'redis',
    'connection' => 'default',
    'queue' => 'default',
    'retry_after' => 350,
],

并且有多个作业进程 运行ning - 最多 35 个进程 。可以想象,这会占用大量服务器内存。这些过程似乎只是闲逛。 top中显示的这些进程的命令是:

php7.1 artisan queue:work redis --once --queue=linkqueue --delay=0 --memory=128 --sleep=10 --tries=1 --env=local

如果超时为 240 秒,作业如何 运行 持续 45 分钟?为什么有这么多进程 - 不应该只有一个吗?

此外,关于为什么提取 link 的脚本需要 45 分钟才能 运行 的任何想法?!

该脚本 有效 ,也就是说,在大多数情况下,它 运行 符合预期 - 它只需要很长时间。据我所知,没有错误 reported/logged。

作业中的代码是:

$dom = new DOMDocument;
$dom->loadHTML($html);
$links = $dom->getElementsByTagName('a');

foreach ($links as $a) {
    $link = $a->getAttribute('href');

    $newurl = new URL;
    $newurl->url = $link;
    $newurl->save();
}

更新:另一个简单的工作运行很好,不到一秒钟。特别是上面的 link 工作需要 10 分钟。可能是内存问题还是什么?我还能做些什么来诊断问题吗?当 运行 作为控制台作业的一部分时,提取 links 在 1 或 2 秒内自行运行 运行s。只有在排队的时候才吓坏了。

How can a job run for 45 minutes if the timeout is 240 seconds?

因为您的队列连接上有 'retry_after' => 350,。这意味着如果 Laravel 在 350 秒后没有收到作业的消息 - 它假定作业失败并再次重试。在您的情况下,这会导致一项工作的多个进程。

如果您愿意让您的作业 运行 长达 45 分钟 - 那么您应该将 retry_after 设置为更大的数字。说 3600 即 1 小时。

这样,作业只有在 运行 花费的时间超过 1 小时时才会开始。

您还可以执行以下操作使超时不受限制。

php artisan queue:listen --timeout=0