与PHP守护进程通信的最有效方法是什么? [关闭]

I did some PHP daemon and now I want my PHP webapp to communicate with it, e.g. send XML document to it and receive response after some time. As I would like to avoid file operations over the network (as it involves FTP), what would be the ideal way of sending this document? The PHP daemons and PHP webapps are on different servers. I have investigated various options so far:

  • ActiveMQ, but that adds additional bloatware
  • TCP Sockets (however it's hard to do it as the PHP daemon is single-threaded and very busy sometimes)
  • FTP, SCP to send the file
  • NFS / CIFS
  • Using database

If the messaging server looks like the best option, what would be best suited for PHP? I would like to avoid centralized, single messaging server because it's difficult to approve firewall rules, and the network is very big, complex and very fail-prone. So that would require star-shaped network of messaging servers, and because of that they would need to very lightweight, easy to deploy and with no difficult dependencies.

The answer is obvious: Use TCP but don't use a single threaded programming language for a TCP daemon.

If you want to use PHP for the workers, maybe because you wish them to use a shared PHP library, you can code a most minimal daemon in a programming language which supports threads, and forwards the requests to PHP helper scripts (or pooled, single threaded TCP daeamons if you want to deploy the workers on different hosts, which is good for scalability)

However, a software which fulfils the requirements exists already: Gearman

Communicating with your daemon consists of two completely different aspects:

  • Send data to the daemon
  • Receive data from the daemon

I learned this the hard way, when I had to solve a very similar problem.

Sending data to the daemon is limited by the fact, that the single-threaded daemon cannot easily listen. I solved it this way:

  • When the daemon is idle, it polls a SysV-Messagequeue
  • When a consumer wants to request the daemon, it creates a command file reachable via an unguessable URL. It then transmits that URL to the daemon's SysV-Messagequeue (see below for how)
  • THe idling daemon sees the message, fetches the command file via the URL, works on it
  • The command file has an URL where to post the result to
  • The daemon uses cURL to deliver it.

This comes quite natural for a webapp as a consumer - the heavy lifting is completely done as web requests: Both directions are initiated by the daemon, whenever it is idle.

Now for how to get a message into the daemon: The easiest way is to have some sort of server running there

  • If a webserver is already running on the target machine, use a tiny script, that just accepts the URL from a well-defined set of consumers and queues it
  • If not, inetd or xinetd with either a simple shell script or a few lines of C code can do the trick
  • If you want something a bit more robust you can start a queuer command via SSH

We use all three variations in production with excellent results: If the consumer keeps track of the already-worked-on command files, a double-execution because of a flaky network can easily be ruled out.