【问题标题】:Job has been attempted too many times or run too long作业尝试次数过多或运行时间过长
【发布时间】:2019-04-04 03:28:50
【问题描述】:

我的工作在本地完美无缺,但在生产中我遇到了无法正常工作的问题。我已经用try/catch 包含了整个handle() 并且没有看到任何记录到Bugsnag 的内容,尽管在其他地方部署了许多其他例外情况。

public function handle() {
    try {

        // do stuff

    } catch (\Exception $e) {
        Bugsnag::notifyException($e);

        throw $e;
    }
}

根据Laravel Horizon,此队列作业运行0.0026001930236816406 秒,我从未看到它工作,也从未在failed_jobs 表中看到与此作业相关的任何其他错误。

config/queue.php

    'redis' => [
        'driver' => 'redis',
        'connection' => 'default',
        'queue' => 'default',
        'retry_after' => (60 * 10), // 10 minutes
        'block_for' => null,
    ],

config/horizo​​n.php

'environments' => [
    'production' => [
        'supervisor'        => [
            'connection'    => 'redis',
            'queue'         => [
                'default',
            ],
            'balance'       => 'auto',
            'processes'     => 10,
            'tries'         => 3,

            // 10 seconds under the queue's retry_after to avoid overlap
            'timeout'       => (60 * 10) - 10, // Just under 10 mins
        ],

如果某些原因导致此作业反复重试,我该如何找出原因?我很茫然。

调查至今

  • 我的期望是我应该能够运行查询:
SELECT DISTINCT exception, COUNT(id) as errors
FROM failed_jobs 
WHERE payload LIKE '%[TAG-JOB-HAS]%' 
GROUP BY exception;

要查看更多信息:

作业尝试次数过多或运行时间过长

但这就是我所看到的。

【问题讨论】:

  • 您是否尝试过记录调试语句以证明作业已实际运行?您能否提供有关该工作实际执行的更多信息,也许还有一些代码?它可能以不会产生异常的方式失败
  • "...但是在生产中我遇到了它不起作用的问题" - 什么不起作用?您在日志中看到错误吗?
  • 只是想一想,是不是 Bugsnag::notifyException($e) 行导致了异常,导致 Laravel 重新排队你的工作重试?
  • 什么是“// do stuff”?它会做一些奇怪的事情吗,比如调用 exit() 或 die()?
  • handle函数添加try catch后是否重启了队列?

标签: laravel queue laravel-horizon


【解决方案1】:

我遇到了同样的问题

我通过增加“retry_after”参数来修复它

确保 retry_after 值大于作业运行所需的时间

config/queue.php 文件中

    'connections' => [

    'sync' => [
        'driver' => 'sync',
    ],

    'database' => [
        'driver' => 'database',
        'table' => 'jobs',
        'queue' => 'default',
        'retry_after' => 9000,
    ],

【讨论】:

  • 你知道为什么 retry_after 参数不会影响我本地机器上的队列但会影响服务器上的队列吗?
【解决方案2】:

尝试在 laravel 给出的失败方法中捕获异常

/**
* The job failed to process.
*
* @param  Exception  $exception
* @return void
*/
public function failed(Exception $exception)
{
    // Send user notification of failure, etc...
}

并检查您在本地的默认队列驱动程序是否同步,然后是其预期行为。

【讨论】:

  • 您能否提供更多细节?就像可以在哪里创建此功能以及您所指的文档是什么?还是从 AppServiceProvider 手动执行?
  • @YevgeniyAfanasyev 该方法被放置在使用 Queueable 的作业类中。没有抽象方法或存根,只需添加它。 Laravel 通过反射找到它。
【解决方案3】:

根据documentation,您可以通过两种常见的方式处理作业失败:

  • 使用失败的作业事件
  • 使用failed()方法。

在第一种情况下,您可以使用Queue::failing() 方法处理所有作业。您将收到Illuminate\Queue\Events\JobFailed 事件作为参数,它包含异常。

在另一种情况下,您可以使用failed() 方法,它应该放在您的handle() 方法附近。您也可以接收Exception $exception 作为参数。

例子:

public function failed(\Throwable $exception)
{
    // Log failure
}

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-13
    • 1970-01-01
    • 1970-01-01
    • 2014-03-27
    • 1970-01-01
    • 1970-01-01
    • 2020-06-25
    相关资源
    最近更新 更多