使用 zeroMQ 在 PHP 中进行并行处理

Posted

技术标签:

【中文标题】使用 zeroMQ 在 PHP 中进行并行处理【英文标题】:Parallel processing in PHP using zeroMQ 【发布时间】:2015-08-06 20:24:03 【问题描述】:

一些背景: 我正在用 php 构建一个服务器应用程序,它需要根据用户请求执行许多独立的任务。我的应用程序对速度有严格的要求,所以我想并行执行所有这些任务。

我查看了几种解决方案(例如 gearman、rabbitMQ、zeroMQ),并决定使用 zeroMQ(快速、良好的文档、灵活且不需要代理)。这为我解决了线程之间的通信/同步问题。

问题: 我只想在服务器收到请求时才启动任务(不要有一个长时间运行的进程)。所以我收到一个请求 -> 开始并行计算 -> 将计算结果返回给客户端。一个解决方案似乎是pcntl_fork 但是docs 提到在生产服务器环境中使用它存在一些问题,但并没有真正指定它们是什么?

我的另一个选择是使用proc_open,但我不太喜欢它,因为它需要我以某种方式对输入进行序列化,这似乎不如分叉灵活和快速。它比pcntl_fork 有什么优势吗?

还有其他解决方案吗(仍在使用 php :p)?

【问题讨论】:

您可能已经意识到,PARALLEL 处理是一个比临时分叉更复杂的问题。 [一个不错的帖子。][1] 您可能会重新考虑您的架构是否能够满足 PARALLEL 处理范例。否则,PHP / ZeroMQ 组件将无法挽救该主要故障。如果是,ZeroMQ 必须非常小心地设置,以便为真正的 PARALLEL 处理做好准备。 [1]:***.com/a/27347539/3666197 【参考方案1】:

请谨慎行事,我在您的问题中看到了几个危险信号,这让我相信您关心的是您可能不需要关心的事情,并且您可能不关心您应该关心的事情。

您说您对速度有严格的要求——您是否验证过普通的单线程 PHP 不够快?运行任何基准测试,找出你的瓶颈?如果您的速度要求很高,您甚至可以考虑使用不同的语言,因为 PHP 的所有魅力,它永远不会成为工具箱中最有效的锤子。 Java 是一个很好的选择,如果你的瓶颈是依赖于 IO 的,那么 node.js 是一个很好的选择。 我主要担心的是,如果没有更多信息,这个问题就像premature optimization。这可能是不公平的,您可能忽略了这些细节,因为这不是您问题的核心,但作为一个局外人,我至少想确保您如果还没有考虑过这些事情。

您想避免长时间运行的进程 - 为什么?长时间运行的进程本身并没有什么问题 - 但是当您习惯于 Apache+mod_php 的伪高效“按需”性质时,它确实感觉错了。确保您不会因为不习惯而试图避免某事。

您似乎在描述的是从您的 PHP Web 应用程序中执行并行处理 - 就像您编写的任何其他网页一样,Apache 启动您的 PHP 脚本,该脚本分叉另一个进程,而不是连续执行其操作,并行执行它们,完成并在页面渲染完成时返回给用户。如果这是正确的,那么这里是您原来问题的答案:

您不能在 Web 进程中使用 pcntl_fork,只能在命令行中使用。详细信息在您链接到的页面上,在 cmets 中:

这不是“不应该”的问题,而是“不能”的问题。尽管我已经使用--enable-pcntl 在 PCNTL 中进行了编译,但事实证明它只编译到 PHP 的 CLI 版本,而不是 Apache 模块。 [...] function_exists('pcntl_fork') 返回 false,即使它编译正确。事实证明,它从 CLI 中返回 true,并且只为 HTTP 请求返回 false。所有 pcntl_*() 函数也是如此。

...这意味着您必须将分叉进程作为一个单独的长期运行进程启动,或者您必须使用proc_open 按需启动它,没有办法让它按照我认为你想要的方式工作。

【讨论】:

感谢您的回答。我确实错过了有关 pcntl 的文档中的评论。值得庆幸的是,我们当前的解决方案确实涉及首先调用 proc_open,然后才分叉。 @Jason 非常感谢您再次提及过早优化。作为回头客,我总能在那里找到新的宝石。

以上是关于使用 zeroMQ 在 PHP 中进行并行处理的主要内容,如果未能解决你的问题,请参考以下文章

PHP多进程处理并行处理任务实例(转,备用)

PHP多进程处理并行处理任务实例

PHP 中的并行处理 - 你是怎么做的?

消息队列库——ZeroMQ

什么是 zeromq 用例?

使用 xgboost 和 caret 进行并行处理