我有一个网页,当用户访问它时,会立即向单个PHP脚本发出多个(10-20)Ajax请求,这取决于请求中的参数,返回带有高度聚合数据的不同报告。 / p>
问题是很多报告需要大量的SQL调用来获取必要的数据,在某些情况下,报告可能需要几秒钟才能加载。
因此,由于一个客户端正在向同一个PHP脚本发送多个请求,因此您最终会看到报告在页面上慢慢加载一个。换句话说,生成报告不是并行完成的,因此会导致页面需要一段时间才能完全加载。
有没有办法在PHP中解决这个问题,并且可以并行处理从单个客户端到单个PHP脚本的所有请求,以便可以更快地加载页面及其所有报告?
谢谢。
答案 0 :(得分:3)
据我所知,可以在PHP中执行多线程。 请查看 pthreads extension。
您可以做的是使脚本的报告生成部分/功能并行执行。这将确保每个函数都在自己的线程中执行,并将更快地检索您的结果。此外,设置最大并发线程数< = 10,以便它不会成为资源占用。
Here是一个帮助您开始使用pthreads的基础教程。
还有一些可能有帮助的more examples(特别是你的SQLWorker示例)
答案 1 :(得分:1)
这更多是服务器配置问题,取决于系统上PHP的安装方式:如果使用php-fpm
,则必须增加pm.max_children
选项。如果你通过(F)CGI使用PHP,你必须配置web服务器本身以使用更多的孩子。
您还必须确保数据库服务器允许运行许多并发进程。如果你有足够的PHP进程在运行,那么它将没有任何好处,但是其中一半必须等待数据库注意它们。
例如,在MySQL中,其设置为max_connections
。
您面临的另一个问题是浏览器不会对同一主机执行10-20个并行请求。这取决于浏览器,但据我所知,现代浏览器只能同时打开2-6个连接到同一主机(域)。因此,无论服务器配置如何,任何更多的请求都将排队等候。
如果您使用MySQL,您可以尝试将所有调用合并为一个请求,并使用mysqli::poll()使用并行SQL查询。
如果不可能,您可以尝试在PHP脚本中调用子进程或分叉。
答案 2 :(得分:1)
当然 PHP 可以并行执行多个请求,如果它使用像 Apache 或 Nginx 这样的 Web 服务器。 PHP 开发服务器是单线程的,但这无论如何都应该用于开发。但是,如果您正在使用 php 的文件会话,则对会话的访问是序列化的。 IE。任何时候只有一个脚本可以打开会话文件。解决方案:在脚本启动时从会话中获取信息,然后关闭会话。