与PHP守护进程通信的最有效方式是什么?


What is the most effective way of communicating with PHP daemon?

我做了一些PHP守护进程,现在我希望我的PHP webapp与它通信,例如发送XML文档给它,并在一段时间后收到响应。由于我希望避免通过网络进行文件操作(因为它涉及FTP),那么发送此文档的理想方式是什么?PHP守护进程和PHP web应用程序位于不同的服务器上。到目前为止,我已经研究了各种选择:

  • ActiveMQ,但这会增加额外的臃肿软件
  • TCP套接字(但是很难做到这一点,因为PHP守护进程是单线程,有时非常繁忙)
  • FTP, SCP发送文件
  • nfs/cifs
  • 使用数据库
如果消息服务器看起来是最好的选择,那么什么最适合PHP呢?我希望避免使用集中式的单一消息传递服务器,因为很难批准防火墙规则,而且网络非常庞大、复杂且非常容易出错。因此,这将需要星形的消息服务器网络,正因为如此,它们需要非常轻量级,易于部署,并且没有困难的依赖关系。

与守护程序通信由两个完全不同的方面组成:

  • 发送数据守护进程
  • 从守护进程
  • 接收数据

当我不得不解决一个非常类似的问题时,我才明白这一点。

向守护进程发送数据受到单线程守护进程无法监听的限制。我是这样解决的:

  • 当守护进程空闲时,它轮询一个sysv - messagqueue
  • 当用户想要请求守护进程时,它会创建一个命令文件,通过一个不可猜的URL可以访问。然后,它将该URL传输到守护进程的SysV-Messagequeue(参见下文)
  • 空闲守护进程看到该消息,通过URL获取命令文件,并对其进行处理
  • 命令文件有一个URL,可以将结果发布到
  • 守护进程使用cURL发送。

对于作为消费者的webapp来说,这是很自然的——繁重的工作完全由web请求完成:两个方向都是由守护进程发起的,无论何时它空闲。

现在来看看如何将消息发送到守护进程:最简单的方法是在守护进程中运行某种类型的服务器

  • 如果web服务器已经在目标机器上运行,使用一个小脚本,它只接受来自一组定义良好的消费者的URL并将其排队
  • 如果没有,inetd或xinetd用一个简单的shell脚本或几行C代码可以做到这一点
  • 如果你想要一些更健壮的东西,你可以通过SSH启动队列命令

我们在生产环境中使用了这三种变体,效果非常好:如果用户跟踪已经运行的命令文件,则可以很容易地排除由于网络不稳定而导致的双重执行。

答案很明显:使用TCP,但不要为TCP守护进程使用单一线程编程语言。

如果您想为工作程序使用PHP,也许是因为您希望它们使用共享的PHP库,您可以用支持线程的编程语言编写一个最小的守护进程,并将请求转发给PHP helper脚本(或者如果您想将工作程序部署在不同的主机上,则可以将请求转发给池,单线程TCP守护程序,这有利于可伸缩性)

然而,一个满足要求的软件已经存在:Gearman