In addition to scalability and redundancy, one of the advantages of a virtualized system can be a single point of configuration across multiple servers. This not only streamlines day-to-day maintenance, it can also facilitate making significant system engineering changes.

For example, several months ago, we looked to FastCGI to improve the performance of PHP scripts on our webhosting cluster. These scripts have always run under individual account UIDs for security, via mod_cgi and suexec. However, this additional overhead meant that PHP scripts took longer to run and required more CPU relative to the in-process execution of mod_php.

The ipHouse webhosting platform is a load-balanced cluster of multiple identical web servers. In a non-virtualized system, each of these web servers would have its own set of account and server configuration files (etc/passwd, httpd.conf, usw.) which needed to be maintained and kept synchronized between servers. In our virtualized cluster, each server loads its configuration from centralized sources. All server configuration is stored in a shared file repository, and all user account information is stored in a database and retrieved as required.

After determining the necessary pieces, implementing PHP via FastCGI was relatively trivial. Beside installing the mod_fcgid package, it took just a few changes to the shared server configuration files. After waiting for each server in the cluster to load the updates (an automatic process), we were done. Really, that’s it. Virtually any change is write once, run everywhere.

Technical

# Load the FastCGI module
LoadModule fcgid_module libexec/mod_fcgid.so

# Assign PHP scripts to the FastCGI module
AddHandler fcgid-script .php

# Execute PHP scripts via the fcgid_php wrapper script
FcgidWrapper /webroot/cgi-bin/fcgid_php .php

# Enable additional script path processing
# Make sure that cgi.fix_pathinfo is set to 1 in php.ini
FcgidFixPathInfo 1

# Terminate processes after handling some number of requests
FcgidMaxRequestsPerProcess 10000

The fcgid_php wrapper script is a relatively simple shell which sets up the environment before launching the PHP interpreter.

#!/bin/sh

export PHP_FCGI_MAX_REQUESTS='10001'
ulimit -t 3600
exec /usr/local/bin/php-cgi