使用 zeroMQ 在 PHP 中进行并行处理
Parallel processing in PHP using zeroMQ
一些背景:
我正在 php 中构建一个服务器应用程序,它需要根据用户请求执行许多独立任务。我的应用程序对速度有严格的要求,因此我想并行执行所有这些任务。
我看过几个解决方案(例如 gearman、rabbitMQ、zeroMQ),我决定使用 zeroMQ(快速、良好的文档、灵活且不需要代理)。这为我解决了线程之间的 communication/sync 问题。
问题:
我只想在服务器收到请求时启动任务(不要有一个很长的 运行 过程)。所以我收到一个请求 -> 开始并行计算 -> return 计算结果给客户端。一个解决方案似乎是 pcntl_fork
但是 docs 提到在生产服务器环境中使用它存在一些问题但没有真正说明它们是什么?
我的另一个选择是使用 proc_open
,但我不太喜欢它,因为它需要我以某种方式序列化输入,这看起来不如分叉灵活和快速。它比 pcntl_fork
有什么优势吗?
是否有其他解决方案(仍在使用 php :p)?
仔细阅读,我在你的问题中看到了几个危险信号,这让我相信你担心的事情可能你不需要,而且你可能不关心你应该关心的事情。
你说你对速度有严格的要求 - 你有没有验证过普通的单线程 PHP 不够快? 运行 任何基准,找出你的瓶颈?如果您的速度要求很高,您甚至可以考虑使用不同的语言,尽管 PHP 的所有魅力都不会成为工具箱中最有效的锤子。 Java 是一个不错的选择,如果你的瓶颈是 IO 依赖的,node.js 是一个不错的选择。 我主要担心的是,由于缺少更多信息,这个问题有 premature optimization 的味道。这可能是不公平的,你可能忽略了这些细节,因为这不是你问题的核心,但作为一个局外人,我至少想确保你考虑过这些事情,如果你还没有考虑的话。
您想避免长 运行 进程 - 为什么?长 运行 进程本质上没有错 - 但当您习惯于 Apache+[的伪高效 "on-demand" 特性时,它确实 感觉 错误=34=]。确保您不会因为不习惯而试图避免某些事情。
您似乎在描述的是从您的 PHP 网络应用程序中执行并行处理 - 就像您编写的任何其他网页一样,Apache 启动您的 PHP 脚本,该脚本分叉另一个处理,而不是串行执行其操作,而是并行执行它们,在页面呈现完成时完成并 returns 给用户。如果那是正确的,那么这里是您原始问题的答案:
您不能在 Web 进程中使用 pcntl_fork
,只能从命令行使用 。详细信息在您链接到的页面上,在评论下方:
It's not a matter of "should not", it's "can not". Even though I have compiled in PCNTL with --enable-pcntl, it turns out that it only compiles in to the CLI version of PHP, not the Apache module. [...] function_exists('pcntl_fork') was returning false even though it compiled correctly. It turns out it returns true just fine from the CLI, and only returns false for HTTP requests. The same is true of ALL of the pcntl_*() functions.
... 这意味着您必须将分叉过程作为一个单独的长 运行 过程来启动,或者您必须使用 proc_open
按需启动它,没有办法让它按照我假设的方式工作。
一些背景: 我正在 php 中构建一个服务器应用程序,它需要根据用户请求执行许多独立任务。我的应用程序对速度有严格的要求,因此我想并行执行所有这些任务。
我看过几个解决方案(例如 gearman、rabbitMQ、zeroMQ),我决定使用 zeroMQ(快速、良好的文档、灵活且不需要代理)。这为我解决了线程之间的 communication/sync 问题。
问题:
我只想在服务器收到请求时启动任务(不要有一个很长的 运行 过程)。所以我收到一个请求 -> 开始并行计算 -> return 计算结果给客户端。一个解决方案似乎是 pcntl_fork
但是 docs 提到在生产服务器环境中使用它存在一些问题但没有真正说明它们是什么?
我的另一个选择是使用 proc_open
,但我不太喜欢它,因为它需要我以某种方式序列化输入,这看起来不如分叉灵活和快速。它比 pcntl_fork
有什么优势吗?
是否有其他解决方案(仍在使用 php :p)?
仔细阅读,我在你的问题中看到了几个危险信号,这让我相信你担心的事情可能你不需要,而且你可能不关心你应该关心的事情。
你说你对速度有严格的要求 - 你有没有验证过普通的单线程 PHP 不够快? 运行 任何基准,找出你的瓶颈?如果您的速度要求很高,您甚至可以考虑使用不同的语言,尽管 PHP 的所有魅力都不会成为工具箱中最有效的锤子。 Java 是一个不错的选择,如果你的瓶颈是 IO 依赖的,node.js 是一个不错的选择。 我主要担心的是,由于缺少更多信息,这个问题有 premature optimization 的味道。这可能是不公平的,你可能忽略了这些细节,因为这不是你问题的核心,但作为一个局外人,我至少想确保你考虑过这些事情,如果你还没有考虑的话。
您想避免长 运行 进程 - 为什么?长 运行 进程本质上没有错 - 但当您习惯于 Apache+[的伪高效 "on-demand" 特性时,它确实 感觉 错误=34=]。确保您不会因为不习惯而试图避免某些事情。
您似乎在描述的是从您的 PHP 网络应用程序中执行并行处理 - 就像您编写的任何其他网页一样,Apache 启动您的 PHP 脚本,该脚本分叉另一个处理,而不是串行执行其操作,而是并行执行它们,在页面呈现完成时完成并 returns 给用户。如果那是正确的,那么这里是您原始问题的答案:
您不能在 Web 进程中使用 pcntl_fork
,只能从命令行使用 。详细信息在您链接到的页面上,在评论下方:
It's not a matter of "should not", it's "can not". Even though I have compiled in PCNTL with --enable-pcntl, it turns out that it only compiles in to the CLI version of PHP, not the Apache module. [...] function_exists('pcntl_fork') was returning false even though it compiled correctly. It turns out it returns true just fine from the CLI, and only returns false for HTTP requests. The same is true of ALL of the pcntl_*() functions.
... 这意味着您必须将分叉过程作为一个单独的长 运行 过程来启动,或者您必须使用 proc_open
按需启动它,没有办法让它按照我假设的方式工作。