Home‎ > ‎Knowledge Base‎ > ‎

Apache 2 - HowTo - Tune Apache

Requirements:

You will need to have an understanding of how Apache functions and basic ability to with with BASH and edit configuration files.

The load handling of the Apache service is controlled from the httpd.conf file. Most Linux Server will be under /etc/httpd/conf/httpd.conf however cPanel uses /usr/local/apache/conf/httpd.conf. The most common method is to use the Global Prefork options.

# prefork MPM
# StartServers: number of server processes to start
# MinSpareServers: minimum number of server processes which are kept spare
# MaxSpareServers: maximum number of server processes which are kept spare
# ServerLimit: maximum value for MaxClients for the lifetime of the server
# MaxClients: maximum number of server processes allowed to start
# MaxRequestsPerChild: maximum number of requests a server process serves
<IfModule prefork.c>
StartServers 15
MinSpareServers 10
MaxSpareServers 40
ServerLimit 256
MaxClients 256
MaxRequestsPerChild 1000
</IfModule>

Most of the time you only need to adjust the prefork.c and not worry about the worker.c section. Making adjustments to this is not an exact science as many different variables come into play such as how many sites are hosted, how much traffic is coming through, how many of the pages are static verses having sub functions, are MySQL calls being used, and so on.

The first general rule is that you are trying to balance having as many open connections as possible verses the server load. The more connections that are open generates server load. The more server load, the slower the site will respond. However if there are not enough connections available then the site will not always respond to everyone. This is controled through the following:

    StartServers
How many apache servers start in the very beginning. If this is set too low then it will take some time to catch up to the needed load when restarting the Apache service

    MinSpareServers
How few servers will it go down to to save on RAM and CPU. If this is set too low then it will be slow to respond to sudden peaks in traffic

    MaxSpareServers
Maximum number of servers. If set too low then there will not be enough open sockets for all requests and the site will appear down for some users.

    ServerLimit
Must equal MaxSpareServers if MaxSpareServers is greater than 256

The second general rule is balancing the following two options. A large RAM based Apache configuration that allows many different connections with few instances, or many small RAM based Apache configuration that allows very few connections. The first option is better for a single or very few sites hosting a large database, where the second option is better for running a large number of different sites with little or no database involved. This is controlled through the following:

    MaxClients
How many sessions a server can handle. A rule of thumb to make a good starting point is to set this to 150 times the number of Gigs of RAM on the server.

    MaxRequestsPerChild
How often the service refreshes cached information and or restarts the server to accept new sessions.

So if you are hosting a large database it is better to have a few servers with many clients, where as if you are hosting many different sites it is better to have many different servers with few clients. If you are running a cron job that changes the site dynamically then you want few requests per child so it does not cache the information for too long. After making changes you would then restart the Apache service.

The following commands can be run to check the server load. Note that this should be run while there is peak traffic to the server for the most accurate reading.

Apache 1

echo '##### Apache Load Check 1.2 ###########' ;\
echo '##### Written by Joe Ciancimino 2009 #####'
watch \
"echo "CTRL+C TO EXIT" ;\
clear ;\
echo vmstat ;\
vmstat ;\
echo Load ;\
w ;\
echo Apache Processes ;\
ps -elf |grep 'http' |wc -l ;\
echo Active Apache Conections ;\
netstat -nalp |grep ':80 ' |grep 'ESTABLISHED'|wc -l ;\
echo Apache Conections ;\
netstat -nalp |grep ':80 ' |wc -l ;\
echo SYN Conections ;\
netstat -nalp |grep 'SYN' |wc -l ;\
echo IPCS ;\
ipcs |grep 0x0 |wc -l" ;\
echo '##### End Apache Load Check ##########' ;\

Apache 2

watch "/etc/rc.d/init.d/httpd status"

While a lot of people may give you formulas to determine the settings based on RAM and CPU usage, the result would just be a baseline that still needs to be further tweaked. The main thing is to keep an eye on the load of the server during peak hours. Some say to keep the load around 1 per CPU, but you can usually push it as high as around 4 per CPU with out too much trouble if needed. It would not be considered optimal but rather "Red Lining" the server. If you watch what happens during the startup you may want to increase StartServers to around 30 and might even try pushing MaxSpareServers up to around 60. Any change then restart Apache and watch the load. If you don't have many sites and describe a lot of database usage, instead of pushing the MaxSpareServers up very high, you might try after that to push Max Clients as needed. The other thing you are looking for is in the netstat command is SYN connections.

netstat -nalp | grep ':80 ' | grep SYN

If you see a lot of SYN connections then you still need to increase MaxSpareServers

Once you are satisfied with the performance from tuning the prefork, you may want to further secure Apache from some buffer overflow exploits. While this is described as security, it is actually simply a second layer to how Apache is tuned, so this too will effect the performance of the service.

    RLimitMEM softlimit hardlimit

Limits how much RAM the httpd processes will take.

Suggestion:

Run the command 'free -l' and you should see some thing like:

free -l
total used free shared buffers cached
Mem: 1034584 1015908 18676 0 201960 396040
Low: 903576 885152 18424
High: 131008 130756 252
-/+ buffers/cache: 417908 616676
Swap: 1052248 144 1052104

Take the larger of the two between the Low and High available memory for the first limit and put the Total Mem as the second limit.

RLimitMEM 903576 1034584

    RLimitCPU softlimit hardlimit

Configure the maximum CPU time in seconds used by a process

Suggestion:

Run the command 'cat /proc/cpuinfo' to see how many core processors you have to work with. Use '50 * the number of processors' for the softlimit and '75 * the number of processors'for the hard limit.


cat /proc/cpuinfo
processor : 0
vendor_id : GenuineIntel
cpu family : 15
model : 2
model name : Intel® Xeon™ CPU 2.40GHz
stepping : 7
cpu MHz : 2393.370
cache size : 512 KB
physical id : 0
siblings : 2
core id : 0
cpu cores : 1
fdiv_bug : no
hlt_bug : no
f00f_bug : no
coma_bug : no
fpu : yes
fpu_exception : yes
cpuid level : 2
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe cid xtpr
bogomips : 4788.04

processor : 1
vendor_id : GenuineIntel
cpu family : 15
model : 2
model name : Intel® Xeon™ CPU 2.40GHz
stepping : 7
cpu MHz : 2393.370
cache size : 512 KB
physical id : 0
siblings : 2
core id : 0
cpu cores : 1
fdiv_bug : no
hlt_bug : no
f00f_bug : no
coma_bug : no
fpu : yes
fpu_exception : yes
cpuid level : 2
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe cid xtpr
bogomips : 4783.86

RLimitCPU 100 140

    RLimitNPROC softlimit hardlimit

Limits the number of subprocesses httpd can fork to at any one time such as CGI.

Suggestion:

Would suggest to take the 1/2 the number from the MaxSpareServers for the soft limit and match it for the hard limit.

RLimitNPROC 10 20

So combined it would look some thing like:

RLimitMEM 903576 1034584
RLimitCPU 100 140
RLimitNPROC 10 20

<IfModule prefork.c>
StartServers 15
MinSpareServers 10
MaxSpareServers 40
ServerLimit 600
MaxClients 600
MaxRequestsPerChild 1000
HostnameLookups Off
KeepAlive Off
#KeepAliveTimeout 30
</IfModule>

Comments