Optimising Apache (for AWS EC2 micro or small instances)

In this post I’ll talk about the optimising / configuring I did on Apache. So my site could live happily on its new home of AWS EC2 small instance ( running Amazon Linux ). The guide below covers sites that get maybe a few hundred page views per day (if you have bigger traffic you will probably need a bigger server).

I moved my site to AWS and it kept crashing Apache, I would restart it and it would be fine for while (maybe a few days or a week), then the same thing would happen again.

I looked in to the memory situation with Apache and found out it was launching a number of processes (too many, for the amount of RAM I had on my EC2 instance ). This is what I did to fix it. The command below can be handy to give you a quick view of whats currently being used (memory wise on your server).

free -m

Process

Check which MPM you running ( for small such as mine e.g. 1GB RAM , you want to be running prefork ):

httpd -V | grep MPM      

If that doesn’t say prefork you need to alter Apache conf or one of the conf files ( I had to edit /etc/httpd/conf.modules.d/000-mpm.conf , but it can be different based on your distro, Amazon Linux seems to be quite similar to CentOS 7). Its good practice to always make a backup of any config you change. In your apache dir eg /etc/httpd in my case (grep might help you locate ).

grep -r “prefork”

I had to comment out the other (mpm event module ) and uncomment prefork so I had this loaded:

LoadModule mpm_prefork_module modules/mod_mpm_prefork.so

I then added this in the same file ( grep to check if you have some of this already):

<IfModule mpm_prefork_module>

    StartServers             1

    MinSpareServers          1

    MaxSpareServers          1

    MaxRequestWorkers       15

    MaxConnectionsPerChild   0

</IfModule>

Because my memory was low. I needed to keep the Servers started low and MaxRequestWorkers also. This is how I calculated how to work out MaxRequestWorkers. First I grepped to see how many processes Apache had running:

ps -aux | grep apache

This showed me a bunch of php-fpm that I run this for to see the memory they were taking up:

ps -ylC php-fpm –sort:rss | awk ‘{sum+=$8; ++n} END {print “Tot=”sum”(“n”)”;print “Avg=”sum”/”n”=”sum/n/1024″MB”}’

This was telling me the memory the apache / php-fpm processes where taking up was about 60 MB per each , My MaxRequestWorkers was set to 256, so 256 * 60 MB = over 15GB of RAM required. Essentially Apache in the busier times was trying to simultaneously accept more connections that I had memory for on my EC2 instance ( I only had 600MB ish spare ). So needed to adjust this down ( 10 * 60MB = 600MB ).

MaxRequestWorkers is the amount of concurrent connections Apache will allow, I def need todo some optimising to get this figure up ( I only get maybe 200 page views per day so its ok for my site – and will be for many small sites / apps ).

Apache queues requests after MaxRequestWorkers reaches its max ( so new requests will wait to be serviced, this should be quick but depends, you may need a bigger EC2 instance if you have more traffic than you can handle ).

Other optimisations I did:

The main optimising the fixed my issues was the above, however I also added this to my apache conf file:

Timeout 60

KeepAlive on

MaxKeepAliveRequests 300

KeepAliveTimeout 2

I wont cover these but check out the liquid web link below (which covers these in detail).

Modules I removed:

Removing some Apache modules which would lower the MB used per Apache process ( so I could have more MaxRequestWorkers )

I grepped to find where modules where ( strewn about the place , but mostly in /etc/httpd/conf.modules.d/00-base.conf in my case):

grep -r LoadModule

Removed some modules, didn’t seem to make any difference so put them back in.

TODO: add what I did to my php-fpm config (www.conf)

References:

The video below is excellent:

https://www.linode.com/docs/guides/tuning-your-apache-server/

Leave a Comment