UNIX domain socket IPC for FastCGI

23 November 2009, 10:58
I won't play the smart ass card by writing poems about UNIX socket vs TCP socket. This is (maybe) the best comparison around the web: The TCP socket support for the FastCGI is great as long as the FastCGI load balance feature is used, but for the local inter process communication it just adds useless overhead.

I don't know about most of the FastCGI enabled dynamic interpreters, but I do know that the php-cgi binary (FastCGI enabled) and the php-fpm have support for creating UNIX domain sockets instead of TCP sockets. Also I don't have any information about how much overhead is added by the TCP/IP stack when the FastCGI is involved, but I do know that a RDBMS server such as MySQL is roughly 20% faster through the UNIX socket.

If I am not asking too much (application design issues or other impediments) would you consider the possibility of adding the UNIX domain socket IPC support for the FastCGI feature?

Hiawatha version: 6.18
Operating System: Ubuntu Hardy, Debian Lenny
Hugo Leisink
23 November 2009, 12:20
Can you tell me how to start PHP as a FastCGI daemon listening to a Unix socket instead of a TCP socket?
23 November 2009, 13:58
With PHP-FPM is easier since it completely separates the web server from the FastCGI server as it has its own manager. The connections are configured via pools, where each pool can have its own socket, either TCP or UNIX.

lighttpd's spawn-fcgi is now a separated tool which can be used for the same purpose. Example for launching it with UNIX socket listening:

/usr/bin/spawn-fcgi -n -s /var/run/php-fcgi.sock -u fastcgi-user -U webserver-user -- /usr/bin/php-cgi

The documentation provides an example init script:

I prefer PHP-FPM, mostly because of this: plus the fact that a single daemon can create multiple pools, thus no need to use multiple daemons for running the FastCGI process under multiple system users in order to replace the Apache's suEXEC feature. Actually the lack it, since neither Hiawatha, lighttpd, or nginx won't spawn FastCGI processes, but they depent on external tools, where to be honest, at the moment PHP-FPM is the best.

Your php-fcgi daemon won't bind to a UNIX socket as it exits with this:

PHP FastCGI daemon exited with code 65280

if the bind configuration from the Server directive points to something such as /var/run/php-fcgi.sock. In order to work, a UNIX socket path should be passed to the php-cgi binary via the -b (bind) option. The ip:port option works as documented. I know that the php-cgi binary (FastCGI enabled) says:

-b <address:port>|<port> Bind Path for external FASTCGI Server mode

but it works with UNIX domain sockets as well. Example:

php-cgi -b /var/run/php-fcgi.sock

lighttpd or nginx can use this path in their configuration.

Although the FastCGI specification mentions the Berkeley Sockets only, the official toolkit specifies this:

 * FCGI_Connect --
* Attempts to connect to a listening socket at bindPath.
* if bindPath is in the form of string:int then it is to
* be treated as a hostname:port and we'll connect to that
* socket. Otherwise bindPath is going to be interpreted as
* a path to a UNIX domain socket.
* Results:
* A connected socket, or -1 if no connection could be established.
function: FCGI_Connect

PS: couldn't use the url tag for all the links as the message is sadly marked as spam.
Hugo Leisink
24 November 2009, 00:42
I got it implemented. First tests look oke. Actually, Hiawatha is connecting to PHP via a UNIX socket at this moment
Hugo Leisink
25 November 2009, 10:59
I've done some testing in the meantime, but I don't see any difference in speed...
This topic has been closed.