PHP中使用zeroMQ的并行处理


Parallel processing in PHP using zeroMQ

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

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

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

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

是否有其他解决方案(仍然使用php:p)?

小心点,我在你的问题中看到了一些危险信号,这些信号让我相信你关心的是你可能不需要关心的事情,你可能不关心你应该关心的事情。

你说你对速度有严格的要求——你是否验证过普通的单线程PHP不够快?运行基准测试,找出瓶颈了吗?如果您对速度的要求非常高,您甚至可以考虑使用另一种语言,尽管PHP有很多优点,但它永远不会是工具箱中最有效的工具。Java对于全速运行来说是一个不错的选择,如果瓶颈依赖于IO, node.js是一个不错的选择。我主要担心的是,如果没有更多的信息,这个问题有过早优化的味道。这可能是不公平的,你可能省略了这些细节,因为这不是你问题的核心,但作为一个局外人,我至少想确保你考虑过这些事情,如果你还没有。

你想避免长时间运行的进程——为什么?长时间运行的进程本身并没有什么问题——但是当您习惯了Apache+mod_php的伪高效的"按需"特性时,就会觉得有问题。要确保你不会因为不习惯某事而试图避免它。

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

您不能在web进程中使用pcntl_fork,只能从命令行使用。详细信息在你链接到的页面,在下面的评论中:

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

…这意味着要么您必须将分叉进程作为一个单独的长时间运行的进程启动,要么您必须使用proc_open按需启动它,没有办法让它按照我假设的方式工作。