PHP via FastCGI in Apache on Ubuntu

I maintain a php/mysql website that has occasional traffic spikes which bring the site to a crawl. An Apache process takes up about 10MB on my server that has 1GB of RAM. Apache is set up as mpm_prefork, the default on Linux, which starts an Apache process for each HTTP request. Therefore the machine can serve at most 100 simultaneous requests. If a request is for a video and thus takes a long time to satisfy then this holds an Apache process busy and the limit is soon reached.

The 10MB size of the Apache process is largely down to the embedded mod_php interpreter it uses in order to satisfy requests for php pages. For serving static content the process size is down at about 2MB &endash; that’s five times more requests.

There seem to be two possible solutions:

In both cases Apache is running php therefore in both cases FastCGI stands to improve matters. Therefore I shall try FastCGI first. It also sounds easier.

I worked from an article on HowToForge but it is muddled between FastCGI and suExec. I am only interested in the former. It turned out to be very easy:

  1. Install the packages libapache2-mod-fcgid and php5-cgi.
    I found that libapache2-mod-fcgid was enabled by the installer, but otherwise you will have to a2enmod fcgid
  2. vi /etc/php5/cgi/php.ini and set cgi.fix_pathinfo = 1.
  3. Now change the Apache config, so /etc/init.d/apache2 stop
  4. a2dismod php5
  5. Now set up FastCGI for the website being served:
    <VirtualHost *:80>
            ServerName www.example.com
            ServerAdmin richard@example.com
    
            DocumentRoot /var/www/sites/www.example.com/public_html
    
            PHP_Fix_Pathinfo_Enable 1
    
            <Directory /var/www/sites/www.example.com/public_html>
                    Options +ExecCGI
                    AllowOverride AuthConfig FileInfo Limit
                    AddHandler fcgid-script .php
                    FCGIWrapper /usr/lib/cgi-bin/php .php
                    Order Deny,Allow
                    Allow from All
            </Directory>
    
            ErrorLog /var/log/apache2/error.log
    
            # Possible values include: debug, info, notice, warn, error, crit,
            # alert, emerg.
            LogLevel warn
    
            CustomLog /var/log/apache2/access.log vhost_combined_io
    
    </VirtualHost>
    
  6. Finally, /etc/init.d/apache2 start

It seems to have worked on my test server: an Apache process is now down at under 3MB and there are php processes at 10MB. Next, to see how stable it is on the live server with heavy load and many concurrent requests.


Home | More stuff | Octad of the week