Archive for August, 2008

On PHP, fork() and FastCGI

So, a large number of tools we host are written in PHP. For privacy and security reasons, these scripts need to run as the user who owns them, instead of the web server user, which means we can’t use mod_php, the most common method of using PHP with Apache.

Until now we used something called mod_suphp. This is an Apache module which receives PHP requests, and handles them using suexec and the CGI PHP binary, php-cgi. While this works fine, it creates a large overhead on every request: one fork() and exec() to invoke suexec, and another exec for suexec to run php-cgi.

Fortunately, PHP supports a CGI-replacement called FastCGI. FastCGI runs requests using a persistent daemon process; the web server connects to the process for each request. Since there’s no forking, this is much faster than traditional CGI.

Even though PHP supports FastCGI, neither Apache nor PHP support per-user FastCGI processes — because we want each request to run as the user who owns the script, a seperate PHP daemon is needed for each user. While we could run a seperate PHP for every user, it would use a lot of resources for no reason (we have 300+ users, not all of whom use PHP). The web server configuration to send each request to the right PHP would also be error-prone and difficult to maintain.

Instead, I wrote switchboard. switchboard is a daemon which receives FastCGI requests from the web server, and dynamically creates PHP processes on-demand, running as the appropriate user. After a request is finished, the php-cgi process is kept around to serve the next request for that user. As a side effect, it supports per-user limits on number of processes, which helps to reduce the impact of runaway scripts.

I haven’t done much performance testing, but initial results suggest it significantly reduces load. Right now (due to bugs in earlier versions) it’s not enabled by default for PHP scripts, which makes it harder to see the difference, but once it’s been stable for a while, I’ll probably make it the default handler for PHP.

For more information, and downloads: http://www.flyingparchment.org.uk/pages/switchboard

No Comments