我做了一些PHP守护进程,现在我希望我的PHP webapp与它通信,例如发送XML文档给它,并在一段时间后收到响应。由于我希望避免通过网络进行文件操作(因为它涉及FTP),那么发送此文档的理想方式是什么?PHP守护进程和PHP web应用程序位于不同的服务器上。到目前为止,我已经研究了各种选择:
- ActiveMQ,但这会增加额外的臃肿软件
- TCP套接字(但是很难做到这一点,因为PHP守护进程是单线程,有时非常繁忙)
- FTP, SCP发送文件
- nfs/cifs 使用数据库
与守护程序通信由两个完全不同的方面组成:
- 发送数据到守护进程
- 从守护进程 接收数据
当我不得不解决一个非常类似的问题时,我才明白这一点。
向守护进程发送数据受到单线程守护进程无法监听的限制。我是这样解决的:
- 当守护进程空闲时,它轮询一个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