【问题标题】:Running multiple Symfony commands at once一次运行多个 Symfony 命令
【发布时间】:2013-05-27 19:53:35
【问题描述】:

我在我的 Symfony 设置中实现了一个命令,该命令从数据库中获取一个作业,然后对其进行处理。

如何一次运行多个命令实例,以更快地完成作业。我知道 PHP 不支持多线程,但看到命令是从 shell 调用的,我想知道是否有解决方法。

调用命令使用:

app/console job:process

【问题讨论】:

标签: php multithreading symfony command


【解决方案1】:

我解决这个问题的方法是使用具有多个工作人员的工作队列。它比手动运行多个进程和担心并发更容易管理和扩展。

我发现用于使用 php/symfony 的最简单的通用队列是 beanstalkd,您可以使用 LeezyPheanstalkBundle 将其集成到 symfony2 中

【讨论】:

  • 通过让Commandn 个实例充当工作者来实现这一点。然后是一个 shell 脚本,以确保没有工人成为僵尸。谢谢!
【解决方案2】:

一般来说,我建议使用enqueue 库。您可以从各种可用的传输中进行选择,从最简单的文件系统和 Doctrine DBAL 到真正的一次性传输(例如 RabbitMQ 和 Amazon SQS)。

关于消费者,您需要某种流程管理器。有几种选择:

  1. http://supervisord.org/ - 您需要额外的服务。它必须正确配置。

  2. this 这样的纯 PHP 进程管理器。基于 Symfony 进程组件和纯 PHP 代码。它可以处理进程重启、正确退出 sigterm 信号等等。

  3. this 这样的php\swoole 进程管理器。它需要一个 swoole PHP 扩展,但它的性能是惊人的。

【讨论】:

    【解决方案3】:

    我写了一篇关于如何解决这个确切问题的博文。 https://plume.baucum.me/~/Absolutely/running-multiple-processes-simultaneously-in-a-symfony-command

    在这里重新散列所有内容太长了,但基本概念是您的命令可以选择接受作业的 ID。该命令将检查是否提供了 ID。如果没有,那么它将从数据库中获取所有作业,循环它们,并使用作业 ID 参数调用自身。随着每个命令的启动,您将其存储在一个数组中,如果数组太大,您就进入睡眠状态,以进行速率限制。当命令完成时,您将它们从数组中删除。

    当使用作业 ID 运行命令时,它将使用 Symfony's lock component 创建一个锁,这样一个作业就不会意外地一次被处理两次。当作业完成或出错时解锁作业很重要。一旦有了 ID 和锁,它就会调用您编写的任何代码来实际处理该作业。

    使用这种技术,我将需要花费数小时才能运行的命令(因为它同步执行每个任务)变成了只需几分钟。确保尝试不同的限制来平衡资源利用率和执行任务所需的时间。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-04
      • 1970-01-01
      • 2013-06-08
      • 2018-06-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多