工作尝试次数太多或运行时间太长

Web*_*net 11 queue laravel horizon

我有一份在当地完美无瑕的工作,但在生产中我遇到了无法解决的问题.我已经涵盖了整个handle()try/catch和部署,尽管许多其他例外我没有看到任何东西记录到Bugsnag,在其他地方.

public function handle() {
    try {

        // do stuff

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

        throw $e;
    }
}
Run Code Online (Sandbox Code Playgroud)

根据Laravel Horizo​​n的说法,这个队列作业运行了0.0026001930236816406几秒钟,我从来没有看到它工作,也从未在failed_jobs表格中看到任何与此工作相关的其他错误.

配置/ queue.php

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

配置/ 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
        ],
Run Code Online (Sandbox Code Playgroud)

如果有什么东西导致这项工作一遍又一遍地重试,我怎么知道如何?我不知所措.

调查迄今为止

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

要查看以下错误消息:

工作尝试次数太多或运行时间太长

但这就是我所看到的.

  • Laravel Horizo​​n的仪表板显示有问题的工作运行时间<1秒,所以我知道它实际上没有超时.

Yas*_*ser 14

我有同样的问题

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

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

config/queue.php文件中

    'connections' => [

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

    'database' => [
        'driver' => 'database',
        'table' => 'jobs',
        'queue' => 'default',
        'retry_after' => 9000,
    ],
Run Code Online (Sandbox Code Playgroud)

  • 您是否知道为什么 retry_after 参数不会影响本地计算机上的队列,但会影响服务器上的队列? (3认同)

小智 6

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

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

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

  • @YevgeniyAfanasyev 该方法放置在使用 Queueable 的作业类中。没有抽象方法或存根,只需添加它即可。Laravel 通过反射找到它。 (2认同)

小智 6

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

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

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

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

例子:

public function failed(\Throwable $exception)
{
    // Log failure
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助。