在我们的LAMP站点上,我们遇到了一些服务必须多次调用数据库来提取数据的问题。通常在PHP中(至少在我的经验中)是串行的;这显然是低效的。我们可以通过使用缓存和聚合一些查询来缓解一些低效率;但是在某些情况下,我们仍然需要执行多个db调用。
理想情况下,我只是发送尽可能多的请求到数据库或web服务在同一时间异步,但PHP似乎不支持这种模式开箱即用。以下是我所知道的解决方法。
我们目前使用Gearman来处理异步任务。我可以将我们的一些服务重写为Gearman任务,并使用它对数据库和服务进行异步调用。然而,我们也有过Gearman占用大量进程和内存的糟糕经历;在某些情况下,当生产服务器变得无响应时,强制我们重新启动它们。但是,我相信由于脚本中的一些错误,我能够跟踪这个问题,并相信我已经修复了它。但是我觉得如果我们使用Gearman作为处理异步任务的任务池/管理器,这种不稳定性和过度的资源消耗可能会再次出现。
或者,我正在查看pthreads。它似乎是一个更好的选择,因为它不需要运行Gearman守护进程来工作,而且它完成了我想要的。在它上面甚至似乎有一个像样的框架。我们决定配置一个启用pthreads的测试服务器。然而,我们不知道的是pthreads需要改变我们的Apache配置,特别是转到httpd。来自httpd的Worker(又名prefork)。诚然,我不是一个有经验的Apache管理员,所以我甚至不确定做这个改变会有什么后果。正因为如此,现在我对使用它犹豫不决,至少在我有时间进一步研究它之前。
所以我的问题是,如果我想在PHP中做异步请求,我应该坚持使用Gearman知道我可能会遇到问题,或者我应该冒险去用pthreads,即使它似乎需要改变我们的Apache配置,我很坦率地说,不知道它会如何影响我们的网站?或者,也许还有另一种我还不知道的选项。
服务器配置:
PHP 5.6.1- Apache 2.4.12
- Red Hat Enterprise 6.3 MySQL 5.5.28
- 8 gb RAM
首先,在异步并发性和并行并发性之间存在着深刻的混淆。
异步执行意味着单个任务的指令是交错的,这样任务就可以并发地相对于其他任务运行。
并行执行意味着单个任务的指令并行执行,使得它们在时间上并发运行。
你可以在这里找到更完整的异步和并行并发的解释,还有漂亮的图片。
Gearmans的多处理模型允许并行执行,pthreads也是如此。
当你说PHP不支持异步执行时,这是错误的
这是错误的,因为异步执行并不需要语言支持来实现。只是交错指令并不复杂,这里有一个例子,可以在我们需要关心的任何版本的PHP上工作。
像这样的交错指令会导致代码混乱,并且只有在非阻塞I/O的情况下才值得这样做。在这种情况下,交错指令允许您在同步阻塞代码迫使您等待时执行另一个任务的指令,从而消除等待。这减少了总执行时间。现代版本的PHP确实有一些工具(生成器)使这变得更好,并且正如您已经知道的,存在许多框架来抽象尽可能多的困难。
现在,我们开始在web服务器的前端使用pthreads。在最新版本的pthreads中,这是强制禁用的。没有好的理由,也没有好的时间在web应用程序的前端创建(真正的,内核的)线程,它永远不会有意义。
有关该决定的更多细节,请阅读此
所以,展望未来,你的预期用途是不可能的。
没有什么比说pthreads' got this
更让我高兴的了,但我不认为这是真的。我认为你把重点放在了错误的优化上。
如果你的数据库模式或服务器有问题,那么解决这个问题。如果你需要向外部API发出多个请求,那么尽可能采用最简单的路线;异步非阻塞I/o
在任何特定任务中以gearman或pthreads的形式抛出线程只能保证做一件事;让它更复杂.