在Laravel的工匠队列中捕获ProcessTimedOutException:listen

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Laravel的工匠队列中捕获ProcessTimedOutException:listen相关的知识,希望对你有一定的参考价值。

我们有一堆SQS工作,我们使用Laravel的php artisan queue:listen观察和处理。

定期,有几分钟的短暂和SQS超时。发生这种情况时,queue:listen会中止一条消息:

[SymfonyComponentProcessExceptionProcessTimedOutException]                                                                                             
  The process "php artisan queue:work
    --queue="https://sqs.us-west-2.amazonaws.com/*******/queue"
    --delay=0 --memory=128 --sleep=3 --tries=0 -env=production"
  exceeded the timeout of 60 seconds.

我试过在app/start/global.phpapp/start/artisan.php中处理异常:

App::error(function(SymfonyComponentProcessExceptionProcessTimedOutException $exception) {
    // do nothing
});

不幸的是,例外仍然发生,我的queue:listen仍然死亡。

如何捕获此异常并忽略它以进行重试?

答案

如果它有帮助,我使用SupervisorD来运行crons并且我从队列中解雇:每秒工作一次,我对SQS没有任何问题。

另一答案

您要么在异常处理程序中重新运行“php artisan queue:work ...”队列作业,

或者将/ vendor / symfony / process / Symfony / Component / Process / Process :: setTimeout()值增加到更高的值。

或者两者都有。

另一答案

不是答案,但更像是解决方法:

每当我需要确保进程将运行甚至错误发生我使用npms forever。这个方便的工具一旦崩溃就会重新启动进程。

安装非常简单:

sudo apt-get install nodejs
sudo apt-get install npm
sudo ln -s /usr/bin/nodejs /usr/bin/node
sudo npm -g install forever

使用此命令启动进程:forever start -c php artisan queue:listen 如果你需要阻止它:forever stopall

另一答案

超时将不时发生。 Symfony Process类有自己的超时设置,导致此特定超时(我相信)。我不确定如果不编辑与工作者有关的核心Laravel代码就可以捕获这个,这不是一个好主意。

我强烈建议使用Laravel文档中显示的主管:

https://laravel.com/docs/5.1/queues#supervisor-configuration

这将自动重启您的侦听器,即使它失败。

另一答案

问题似乎与队列作业运行时间有关,据我所知,默认运行时间为30秒,你应该增加这个值,你可以增加两种方式,

php artisan queue:listen --timeout=1200

或者你可以为特定的工作设置$timeout

 /**
 * The number of seconds the job can run before timing out.
 *
 * @var int
 */
public $timeout = 1200;

我希望这个能帮上忙

另一答案
<?php

namespace App;

use IlluminateBusQueueable;
use IlluminateContractsQueueShouldQueue;
use IlluminateFoundationBusDispatchable;
use IlluminateQueueInteractsWithQueue;
use IlluminateQueueSerializesModels;


abstract class Job implements ShouldQueue, JobStatusInterface
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public $tries = 1; // try only once

    public function handle()
    {

    }
}

使用这个抽象类并将它分发给它解决你的问题的扩展类

<?php

namespace App;

use AppJob;
use Log;
use Exception;
/**
 * Class CheckStockJob
 */
 class CheckStockJob extends Job
 {
     public $tries = 100; // how many you need to retry
     public function handle()
     {
        try {
          // do something here
        }
        catch(Exception $e){
          Log::error($e);
          throw $e; // rethrow to make job fail
        }
     }
 }

你代码中的某个地方

$t = new CheckStockJob();
dispatch($t);
另一答案

尝试通过执行以下方法调查命令的可用参数:

php artisan queue:listen --help

您可以以秒为单位传递超时值,尝试次数等。

以上是关于在Laravel的工匠队列中捕获ProcessTimedOutException:listen的主要内容,如果未能解决你的问题,请参考以下文章

无法获得工匠队列:在 Elastic Beanstalk (Laravel/Redis) 上使用主管处理作业

运行工匠队列:在动态多租户多数据库系统上工作

Laravel 工匠迁移失败

Laravel - 捕获 php artisan 命令

在 laravel 中使用 Supervisor 运行棘轮 websockets 和队列

如果工人作为守护进程运行,Laravel 排队的作业不会出现在新的遗物中