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:
lighthttpd
on port 80 and reverse proxy requests
for php
to Apache on port 81, say./data
, so anything not in there
should be passed back to Apache.
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:
libapache2-mod-fcgid
and php5-cgi
.libapache2-mod-fcgid
was enabled by the installer, but
otherwise you will have to a2enmod fcgid
vi /etc/php5/cgi/php.ini
and set cgi.fix_pathinfo = 1
./etc/init.d/apache2 stop
a2dismod php5
<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>
/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.