Laravel队列作业同时触发且不在作业表中显示

33

我正在使用Laravel队列来评论Facebook帖子。每当我从Facebook webhook接收数据时,根据接收到的详细信息在帖子上进行评论。为了处理来自Facebook Webhooks的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 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()函数,所有任务都在同时进行但没有进入队列。这些任务都没有存储在任务表中。我已经尝试了延迟,但仍然没有效果。

以下是我的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

数据库队列对我没起作用,因为它发送到了不同的通道。 - Sakezzz
13个回答

51
使用队列之前,你需要做一些工作:
在.env文件中,你需要将QUEUE_DRIVER或QUEUE_CONNECTION(较新版本)从sync更改为database, 所以打开.env文件并按照以下步骤进行操作。
QUEUE_DRIVER=database

或者

QUEUE_CONNECTION=database

在此之后,您应该使用Artisan命令在数据库中创建队列表:
php artisan queue:table
php artisan migrate

为了确保没有配置缓存
php artisan config:clear

最后,你应该使用php artisan queue:listenphp artisan queue:work来运行你的队列。

是的,我已经完成了这个操作,在输入“php artisan:listen”命令后,当数据正在处理时,命令提示符上没有任何输出。 - Punabaka Abhinav
1
有趣的是,我将其设置为“数据库”,不得不改回“同步”才能使其正常工作。感谢正确的提示! - LinusGeffarth
仅供参考,对于较新的Laravel版本(我不知道哪个版本应用了这个更改,但我正在使用v7.23.2),.env文件中的QUEUE_DRIVER已更改为QUEUE_CONNECTION - Dani Fadli
我没有生成这个队列表。还需要运行php artisan config:cache。非常感谢。 - Imran Hossain
@ImranHossain,你应该运行config:clear而不是config:cache!当新用户运行配置缓存时会遇到更多问题。 - Mahdi Youseftabar
显示剩余6条评论

39

我曾经遇到同样的问题,如果你正在使用Laravel 5.7或更高版本,请在.env文件中使用以下内容。

QUEUE_CONNECTION=database

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

php artisan config:clear

当函数无法使用delay()时,我遇到了相同的问题,因为artisan缓存。 所以清除artisan缓存来解决。 - Hung
这对我很有帮助。许多博客文章没有提到在某些配置更改后必须清除缓存。 - kkatusic
1
如果您从未运行过配置缓存命令,它将永远不会缓存配置,这是在开发中应该做的事情(永远不要运行配置缓存)。 - Toskan
我的队列因为这个问题没有运行。非常感谢。 - Imran Hossain

17
在我的情况下,我使用自定义队列名称来分组我的作业。
ProcessCourseInteractions::dispatch($courseProcessing)->onQueue('course_interactions');

该队列未被执行:

php artisan queue:work

php artisan queue:listen

我需要指定队列名称(适用于工作和监听):

php artisan queue:work --queue=course_interactions

它对我有效。谢谢! - Prabhu Nandan Kumar

9

确保你的应用程序不处于维护模式... 我将我的应用程序置于维护模式,但允许我的本地IP地址... 我无法弄清楚为什么它没有运行。 我最终不得不调试WorkCommand才找出问题...

./artisan up;


9

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

这也适用于 Redis - 在较新的 Laravel / Horizon 中发现 QUEUE_DRIVER 不够用。浪费了 2 小时!谢谢 :) - codinghands

4

对我来说,被接受的答案是一个问题,但我也遇到了其他两个类似的问题,我解决了它们,也许它们会帮助其他人。

其他问题1:作业创建(构造函数)正常工作,但作业处理程序从未触发。

  • 从未在这里很关键,因为通常,如果它们从未触发,则可能是因为您的作业代码已被修改,您的队列应该重新启动。

其他问题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();
    }
}
但是不要这样做,除非你丢掉工作并强制回滚。我的情况很特殊,因为我的工作会在致命错误时发送电子邮件,所以我希望它能够触发,因为无论如何都会有一个错误打破进程(回滚将发生,由于未捕获的错误而没有计划)。
以下是您不想这样做的情况:
  • 当付款成功时,您的工作会向用户发送电子邮件
  • 您的付款可能成功,也可能失败
  • 根据成功的付款,您会回滚或提交
您应该在回滚或提交之后进行调度。对于我的工作,我没有这个奢侈,因为它发生在我无法预测的时候(致命错误)。但是,如果您可以控制它,比如知道您的付款成功了,请在提交或退出所有事务级别之后再进行调度!
我不确定在事务中触发作业的行为,然后回滚或提交。如果它不能正常工作,那么可以通过添加延迟来解决,但这似乎不可靠(猜测需要等待多长时间),除非它是一个显著的延迟。

谢谢。你节省了我半个小时的时间。 - jewelhuq
1
是的,在我的情况下,一切都正确,只是在更改后我没有重新启动队列工作程序。1)“php artisan queue:work” 或者 2)php artisan queue:restart - Santosh Kumar

3

设置 .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

2

我发现你已经有了队列表。

尝试运行php artisan queue:listen --tries=3php artisan queue:work等命令。

队列工作是为了执行每个命令中的一个任务。所以如果表中有20个任务,你可能需要运行20次队列工作。这就是为什么可以运行queue:listen命令。但它会占用大量CPU资源。

在服务器上,你可能希望在后台运行最多3次的队列监听器。

在终端/命令提示符中SSH到你的服务器。然后进入存储artisan文件的项目目录。运行此命令:

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

在这种情况下,任务将自动在后台处理。你只需分派任务。我建议使用失败任务表,如果你正在使用后台队列监听器。

希望这可以帮助你。


谢谢您的回复,我已经找到了解决方法,我没有将queue_drive更改为database。 - Punabaka Abhinav

1

针对那个问题的未来读者,如果队列之前可以工作但现在不行了,尝试在数据库中删除jobs表中的所有内容,这对我起了作用。


1

Simply set QUEUE_CONNECTION=database in .env file


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接