【问题标题】:Multiple Queues in LaravelLaravel 中的多个队列
【发布时间】:2018-05-29 04:58:04
【问题描述】:

我正在 laravel 中创建一个 Web 应用程序,其中用户在多个游戏中进行竞价。前端用户和 cron 作业也正在执行投标。 Cron 作业在每一秒后对每场比赛进行竞标。因此,当同时访问同一行时,出价之间会发生一些冲突。为了解决并发问题,我决定使用 laravel 队列进行投标。但是我有多个游戏,因此我希望同时对每个游戏进行出价。我不希望同时处理同一游戏的出价,因为这样可能会出现并发问题。我想了解 laravel 中的多队列系统。在互联网上搜索后,我了解了多个队列,例如

php artisan queue:work --queue=myJobQueue, myJobQueue1, myJobQueue2,..myJobQueue7

但我不确定它是如何工作的。请有人详细解释一下,所有 7 个队列同时或一个接一个地工作。

【问题讨论】:

    标签: php laravel queue


    【解决方案1】:

    正在寻找queue:listen 命令?

    queue:work 将处理队列驱动程序存储的所有待处理作业,而queue:listen 将等待向其抛出作业以在它们到来时执行它们。

    如果您执行php artisan queue:listen --queue=myJobQueue, myJobQueue1, myJobQueue2,..myJobQueue7,则会创建 7 个队列并自行侦听新任务。

    在您的代码中,您可以分派如下作业:

    dispatch((new MyJob)->onQueue('myJobQueue'));
    

    您可能想要使用像Supervisor 这样的工具来确保queue:listen 始终在后台运行。

    希望这会有所帮助!

    【讨论】:

      【解决方案2】:

      php artisan queue:work --queue=myJobQueue, myJobQueue1, myJobQueue2,..myJobQueue7 设置队列执行的优先级。因此,myJobQueue 上的所有作业都将被执行,然后依次执行myJobQueue1 上的作业,然后按顺序执行到myJobQueue2

      但是,如果您希望这些队列上的作业同时执行,您可以在后台运行每个队列。

      php artisan queue:work --queue=myJobQueue & php artisan queue:work --queue=myJobQueue1 & php artisan queue:work --queue=myJobQueue2 &

      这将在后台将每个队列作为单个进程运行。

      【讨论】:

      • Btu 我们如何配置 myJobQueue 和 myJobQueue1,2... 的配置在哪里?
      • 记得去掉逗号后面的空格,否则命令报错(我在windows上遇到过)命令应该是:php artisan queue:work --queue=myJobQueue,myJobQueue1
      【解决方案3】:

      就像 Ben V 所说,强烈建议使用Supervisor 来保持工作人员始终处于活动状态,特别是如果您希望每个队列运行一个或多个工作人员,或者如果您希望同时处理队列。

      这里是一个示例 Supervisor 配置文件:

      [program:laravel-worker-myJobQueue]
      process_name=%(program_name)s_%(process_num)s
      command=php artisan queue:work --queue=myJobQueue
      numprocs=8
      autostart=true
      autorestart=true
      
      [program:laravel-worker-myJobQueue1]
      process_name=%(program_name)s_%(process_num)s
      command=php artisan queue:work --queue=myJobQueue1
      numprocs=1
      autostart=true
      autorestart=true
      

      上面的配置为myJobQueue创建了8个worker,为myJobQueue1创建了一个worker,因为多个worker可以帮助加快速度,但是对于尝试访问数据库中同一行的作业可能会造成麻烦,其中如果您只想将事情限制为 1 个工作人员。

      然后您只需使用

      将作业分派到正确的队列
      dispatch((new MyJob)->onQueue('myJobQueue'));
      

      dispatch((new MyJob)->onQueue('myJobQueue1'));
      

      【讨论】:

      • 不幸的是,我使用了相同类型的主管配置,但似乎在 worker1 完成后我的工作正在队列中处理。它不会同时发生。
      【解决方案4】:

      这可能是旧的,但以防万一,所有的答案都是正确的,但是您必须将 .env 变量 QUEUE_CONNECTION 设置为同步以外的其他值,如果您的配置设置为同步,它将按顺序执行每个作业进入队列(从而完成一个然后开始下一个),如果它设置为数据库或redis,它将在需要时并行执行作业(这是设置优先级的想法)你应该查看这篇文章(它帮助了我) https://medium.com/hexavara-tech/optimize-laravel-with-redis-caching-made-easy-bf486bf4c58 您还需要在 config/queue.php 中配置队列,例如在 'connections' 数组中:

          'database' => [
              'driver' => 'database',
              'table' => 'jobs',
              'queue' => ['default','another_queue'], //this is just 'default' by default
              'retry_after' => 90,
          ],
      

      这适用于该文件中的所有其他配置。

      【讨论】:

        【解决方案5】:

        如果您在本地机器上进行测试,您可以在项目中创建一个.bat 文件,然后在该 bat 文件中输入这些行

        start "" php artisan queue:work --queue=low
        start "" php artisan queue:work --queue=low
        start "" php artisan queue:work --queue=low
        start "" php artisan queue:work --queue=low
        start "" php artisan queue:work --queue=low
        start "" php artisan queue:work --queue=low
        start "" php artisan queue:work --queue=low
        start "" php artisan queue:work --queue=low
        start "" php artisan queue:work --queue=low
        start "" php artisan queue:work --queue=low
        start "" php artisan queue:work --queue=low
        

        一行代表一次一个队列 10 表示同时运行 10 个队列。

        另外,我包括 --queue=low 因为我的队列很少。

        这仅适用于在线生产结账主管的本地机器。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-07-17
          • 2020-04-21
          • 1970-01-01
          相关资源
          最近更新 更多