Apache is a powerful, reliable and capable web server. The single biggest hardware issue affecting Apache webserver performance is RAM. In Linux by default Apache use Prefork MPM which is memory intensive module. So, server with less memory struggles if requests increase. Addressing the issue, many server experts suggest two things
- Replace Apache by Nginx which is light and fast webserver
- Use Worker MPM and install PHP-FPM module
There are many reasons you would not like to replace your favorite webserver and you are not so technical to do that. But, you can overcome the situation using Varnish as frontend caching server and Apache as backend webserver.
In this post I will show the optimization of Apache webserver with Varnish installation keeping Apache modules as it is.
- Check your total and average Apache process size by the command in Redhat/CentOs
#ps -ylC httpd | awk '{x += $8;y += 1} END {print "Apache Memory Usage (MB): "x/1024; print "Average Process Size (MB): "x/((y-1)*1024)}' Apache Memory Usage (MB): 679.89 Average Process Size (MB): 19.42 Configure appropriate number of child processes.
- Check which MPM is working. By default in Unix/Linux it is prefork.
# httpd -V | grep "Server MPM" Server MPM: Prefork
- Check prefork configuration
Under prefork configuration() , Each process handles one connection at a time. The default configuration of Apache in Redhat/CentOs machine ( /etc/httpd/conf/httpd.conf) is<IfModule prefork.c> StartServers 8 MinSpareServers 5 MaxSpareServers 20 ServerLimit 256 MaxClients 256 MaxRequestsPerChild 4000 </IfModule>
The most important parameters are MaxClients and ServerLimit. MaxClients=256 means, your sever will accept 256 request simultaneously and ServerLimit=256 means Apache is capable of processing 256 process simultaneously. The Maxcleints and ServerLimit should be kept always same in prefork settings. This is good for medium traffic webpage. But even this default configuration can make your webserver hugely loaded due to lacking of memory. As instance, your server is processing 256 simultaneous request. So 256 child processes are spawned and child process consumes on average 15MB memory(we already know it) . Then Apache needs
15*256=3840MB memory
10% of totals memory always should be reserved for OS. If your server hosts Database also like MySQL and it requires 1GB memory, your memory requirement goes to
3840+1024=4864MB
As we consider your physical server has 4GB memory , you should tune Maxclients and ServerLimit. The calculation is follows
Memory For Database: 1024MB 10% reserve for OS : 410MB Remaining: 4*1024-(1024+410)=2662MB MaxClients=2662/Average Process Size=2662/19.42=137
So for Server with 4GB memory has the following configuration
<IfModule prefork.c> StartServers 8 MinSpareServers 5 MaxSpareServers 20 ServerLimit 137 MaxClients 137 MaxRequestsPerChild 4000 </IfModule>
If it is only webserver then you can allocate more memory to Apache. If you have 8GB memory then calculation will be
Memory For Database: 1024MB 10% reserve for OS : 819MB Remaining: 8*1024-(1024+819)=6349MB MaxClients=6349/Average Process Size=6349/19.42=327
So, the more physical memory, the more value of MaxClients and ServerLimit can be configured.
Now you have Apache tuned. But along with Apache, Varnish will significantly improve your performance as it responses static pages from cache. After installation of Varnish, for same number of simultaneous requests less requests go to Apache as many of them will be served by Varnish. So, you can consider your webserver simultaneous requests handling capacity is two or three times than earlier. Here I will describe how to install Varnish in Redhat/CentOs and configure it to work with Apache.
Installation of Varnish caching server
- Check Server Architecture
# uname -a Linux localhost.localdomain 2.6.32-220.el6.x86_64 #1 SMP Wed Nov 9 08:03:13 EST 2011 x86_64 x86_64 x86_64 GNU/Linux
- Get the latest stable RPMs repo from the page https://www.varnish-cache.org/installation/redhat and install it
#rpm --nosignature -i http://repo.varnish-cache.org/redhat/varnish-3.0/el6/noarch/varnish-release/varnish-release-3.0-1.el6.noarch.rpm
- Install Varnish by yum command
# yum install varnish
- Edit /etc/sysconfig/varnish file
# vi /etc/sysconfig/varnish
- Edit the following lines
VARNISH_LISTEN_PORT=80
This is the listing port of Varnish and it is obviously http port(80). http traffic will come first Varnish then forwarded to Apache. So Apache listening port should be changed other than 80.
VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1 VARNISH_ADMIN_LISTEN_PORT=6082
These are the listening address and port to run some administrative command.
Save and exit out of that file. - Open up the /etc/varnish/default.vcl file
# vi /etc/varnish/default.vcl
This file tells varnish where to look for the webserver content. Although Apache listens on port 80 by default, we will change the settings for it later. Within this file, we will tell varnish to look for the content on port 8080. The configuration should like this:
backend default { .host = "127.0.0.1"; .port = "8080"; }
- Configure Apache for working with Varnish
So far we have told varnish that Apache ports will be running on 8080. However the default settings for Apache are still on port 80. We will correct the discrepancy now.
Open up the Apache configuration file:# vi /etc/httpd/conf/httpd.conf
Change the port number for both the NameVirtualHost and the Listen line to port 8080, and the virtual host should only be accessible from the localhost. The configuration should look like this:
Listen 127.0.0.1:8080 NameVirtualHost 127.0.0.1:8080
The Virtual Host should also be set to port 8080, and updated line looks like this:
<VirtualHost 127.0.0.1:8080> ServerAdmin webmaster@dummy-host.example.com DocumentRoot /var/www/html/results ServerName www.example.com ErrorLog logs/example.com-error_log CustomLog logs/example.com_log common </VirtualHost>
Save and exit the file.
- Restart Apache and Varnish to make the changes effective
# /etc/init.d/httpd restart # /etc/init.d/varnish restart
- Allow port 8080 on your firewall if you have firewall enabled
# iptables -I INPUT -p tcp --dport 8080 -m state --state NEW,ESTABLISHED -j ACCEPT
The above configuration is a quick method of optimization of Apache webserver with Varnish installation; and any one can within 15 minutes complete this and enjoy the benefit.