排队的 Laravel 个作业全部同时触发,并且没有出现在作业 table 中

Queued Laravel jobs all fire simultaneously, and don't show up in the jobs table

我正在使用 Laravel 队列在 Facebook post 上发表评论。每当我从 Facebook webhook 收到数据时,我都会根据收到的详细信息对 post 发表评论。为了一次处理来自 Facebook webhook 的 100 个响应,我使用了 Laravel 队列,以便它可以一个接一个地执行。 我使用了 Why Laravel Queues Are Awesome

中提到的分步过程
public function webhooks(Request $request)
{
    $data = file_get_contents('php://input');
    Log::info("Request Cycle with Queues Begins");
    $job = (new webhookQueue($data)->delay(10);
    $this->dispatch($job);
    Log::info("Request Cycle with Queues Ends");
}

这是我的工作class结构

class webhookQueue extends Job implements ShouldQueue
{    
    use InteractsWithQueue, SerializesModels;

    private $data;

    public function __construct($data)
    {
        $this->data = $data;
    }

    public function handle()
    {
       //handling the data here 
    }
}

我一直在点击webhooks()功能,所有作业都在同时工作,但不在队列中。 None 的作业正在存储在作业 table 中。我给了一个延迟,但它也不起作用。

这是我的 laravel.log:

[2017-02-08 14:18:42] local.INFO: Request Cycle with Queues Begins  
[2017-02-08 14:18:44] local.INFO: Request Cycle with Queues Begins  
[2017-02-08 14:18:47] local.INFO: Request Cycle with Queues Begins  
[2017-02-08 14:18:47] local.INFO: Request Cycle with Queues Begins  
[2017-02-08 14:18:47] local.INFO: Request Cycle with Queues Begins  
[2017-02-08 14:18:47] local.INFO: Request Cycle with Queues Begins  
[2017-02-08 14:18:48] local.INFO: Request Cycle with Queues Begins  
[2017-02-08 14:18:48] local.INFO: Request Cycle with Queues Begins  
[2017-02-08 14:18:48] local.INFO: Request Cycle with Queues Begins  
[2017-02-08 14:18:48] local.INFO: Request Cycle with Queues Begins  
[2017-02-08 14:18:48] local.INFO: Request Cycle with Queues Begins  
[2017-02-08 14:18:48] local.INFO: Request Cycle with Queues Begins  
[2017-02-08 14:18:55] local.INFO: Request Cycle with Queues Ends  
[2017-02-08 14:18:55] local.INFO: Request Cycle with Queues Ends  
[2017-02-08 14:18:55] local.INFO: Request Cycle with Queues Ends  
[2017-02-08 14:18:59] local.INFO: Request Cycle with Queues Ends  
[2017-02-08 14:19:00] local.INFO: Request Cycle with Queues Ends  
[2017-02-08 14:19:00] local.INFO: Request Cycle with Queues Ends  
[2017-02-08 14:19:00] local.INFO: Request Cycle with Queues Ends  
[2017-02-08 14:19:01] local.INFO: Request Cycle with Queues Ends  
[2017-02-08 14:19:01] local.INFO: Request Cycle with Queues Ends  
[2017-02-08 14:19:01] local.INFO: Request Cycle with Queues Ends  
[2017-02-08 14:19:01] local.INFO: Request Cycle with Queues Ends  
[2017-02-08 14:19:01] local.INFO: Request Cycle with Queues Ends

要使用队列,您需要做一些工作:

在 .env 文件中,您应该将 queue_driver 从同步更改为数据库, 所以打开 .env 并执行以下操作

queue_driver=database

之后你应该使用 artisan 命令在你的数据库中创建队列 table :

php artisan queue:table
php artisan migrate

并确保没有配置缓存

php artisan config:clear

最后你应该 运行 你的队列 php artisan queue:listenphp artisan queue:work

我看到您已经有 Queue table。

尝试运行宁php artisan queue:listen --tries=3php artisan queue:work

队列工作是为了每个命令只执行一个作业。因此,如果 table 中有 20 个作业,您可能需要 运行 排队工作 20 次。这就是为什么你可以 运行 queue:listen 命令。但是它吃掉了很多 CPU.

在服务器中,您可能希望 运行 您的队列在后台最多尝试 3 次。 在终端/命令提示符中通过 SSH 连接到您的服务器。然后 CD 到 artisan 文件所在的项目目录。 运行 这个命令:

nohup php artisan queue:listen --tries=3 > /dev/null 2>&1 &

在这种情况下,作业将在后台自动处理。你只需要派遣工作。我建议使用 failed-jobs table。如果您正在使用后台队列监听器。

希望对您有所帮助。

Laravel 5.7更新:

.env 中,设置 QUEUE_CONNECTION=database 以便分派的作业转到数据库驱动程序。

然后:

 # Creates a migration for the database table holding the jobs
php artisan queue:table

 # Executes the migration
php artisan migrate

 # Kicks off the process that executes jobs when they are dispatched
php artisan queue:work

我遇到了同样的麻烦,如果你使用Laravel 5.7 or above,在.env文件中使用这个

QUEUE_CONNECTION=database

接下来,像这样清除配置缓存

php artisan config:clear

接受的答案对我来说是个问题,但我也解决了这个问题,因为我解决了其他 2 个类似的问题,也许它们会帮助其他解决这里问题的人。

其他问题 1:作业创建(构造函数)有效,但作业处理程序不触发 - ever

  • ever 是这里的关键,因为通常情况下,如果 none 曾经触发过,那可能是因为你的工作代码被修改了,你的队列应该是重新启动。

其他问题 2:作业创建(构造函数)有效,但作业处理程序不触发 - 有时

  • 有时 对你来说是正确的,那么你的工作没有被解雇可能是因为它们是在交易中发生的,比如 DB::beginTransaction .

假设我想要即使在交易期间也能触发作业,我可以这样做:

/**
 * Create a new job instance.
 *
 * @return void
 */
public function __construct($errorInfo)
{
    $this->errorInfo = $errorInfo;

    // Queues won't run the handlers during transactions
    // so, detect the level, and if it is not 0, rollback to force job handling
    if (\DB::transactionLevel() != 0) {
        \DB::rollBack();
    }
}

但不要这样做,除非你想要解雇你的工作并强制回滚。我的情况很独特,因为我的工作会发送有关致命错误的电子邮件,所以我希望它触发,因为无论如何我都有一个错误中断了这个过程(回滚将会发生并且由于未捕获的错误而计划外)。

在这种情况下您不想这样做:

  • 您的工作会在付款成功后向用户发送电子邮件
  • 您的支付可能会成功,可能不会
  • 根据付款成功,您回滚或提交

您应该将调度安排在回滚或提交之后进行。 我的工作没有那么奢侈,因为它发生在我无法预测的时候(致命错误)。但是如果你能控制它,比如知道你支付成功,在你提交之后发送,或者退出所有级别的交易!

我不确定在事务中触发作业的行为,然后然后回滚或提交。如果它不能通过添加延迟正常工作,它可以解决,但这似乎不可靠(猜测要等待多长时间)除非它是一个显着的延迟。

对于那些问题的未来读者,如果队列以前工作但不再工作,只需尝试从数据库中的作业 table 中删除对我有用的所有内容。

确保您的应用程序未处于维护模式...我的应用程序处于维护模式,但允许我的本地 IP 地址...我无法弄清楚为什么它不是 运行。我不得不最终调试 WorkCommand 以找出...

./artisan up;

不要和我犯同样的错误,

我 运行 php artisan queue:work 在错误的目录中。

只浪费了 30 分钟,本来可以更长。

就我而言,我使用自定义队列名称对作业进行分组。

ProcessCourseInteractions::dispatch($courseProcessing)->onQueue('course_interactions');

该队列未由以下人员执行:

php artisan queue:work

php artisan queue:listen

我需要指定队列名称(对工作和收听有效):

php artisan queue:work --queue=course_interactions

只需在.env文件中设置QUEUE_CONNECTION=database

所有的东西都设置好了,但仍然不能工作,然后确保在 crontab -e 上添加计划 * * * * * cd /var/www/html/<project_name> && php artisan schedule:run >> /dev/null 2>&1

您可以通过以下方式重试(我假设您在 Laravel 文档中做了说明,但有一天它不起作用):

第 1 步:将 table 'jobs' 放入您的数据库。

第 2 步:在控制台中 运行 命令 'php artisan migrate' 再次创建 table 'jobs'。

第 3 步:在控制台运行命令'php artisan queue:work'

第 4 步:重试您的应用

请注意,在 .env 文件中,您设置:

QUEUE_CONNECTION=数据库

QUEUE_DRIVER=数据库

P/s:对我有用!

设置.env

  • QUEUE_CONNECTION=database

添加迁移

  • php artisan queue:table
  • php artisan migrate

如果你使用

  • dispatch(new YourJob($order))->onQueue('queue_name')

最后运行这个命令

  • php artisan queue:work --queue=queue_name