Wednesday, September 14, 2011

The Apache-nginx combo

Apache is one of the most popular web servers of all time. A visit to Netcraft shows that Apache (with more than 54% of the total usage) is still the uncrowned king of web servers. Among a very long list of features, the best are extensibility and reliability. But on a low spec server running Apache 1.x, a large amount of traffic can quickly bring the server to its knees. For each new connection from a client, Apache creates a new process. Thus for a large number of connections, resource consumption is high. In worst cases, the resource consumption is so high it overloads the server and causes it to crash!! and so does your reputation as a Webhost! That is why it is important to be aware of alternatives and how they can sometimes even be used to support your existing web servers.

The Solution:

If the sites you host are a mix of static and dynamic sites, there is a simple way you can stop your server from overloading, and that is by setting up a reverse proxy server. A reverse proxy server can act as a front to one or more web servers you have. All incoming requests are routed via the reverse proxy server and it either:
  • a)handles the request itself, or
  • b)forwards the request to one of the web servers, based on how it is configured.
In a situation where the problem we mentioned earlier occurs, we can use the reverse proxy server to handle requests for static pages, and pass on all other request to your web server(s). One such reverse proxy server we will be talking about today is nginx (pronounced as “engine X“) .

What is Nginx ?

nginx is a HTTP and reverse proxy server, as well as a mail proxy server. According to the March 2010 Netcraft survey, nginx is now used on 12,673,962 domains, making it the fourth most popular web server in use today.
In our case, we want nginx to serve the static files like images, css and html files. Apache will then be dedicated to serve the dynamic content of the website, such as PHP pages. So we will set up nginx as a reverse proxy server to apache.

The How-To:

It is assumed that Apache is running on the server with PHP support.
Login as root to your system and follow the steps below:
1. Stop the Apache service first, this is to make sure no service is listening on port 80
bash# /usr/local/apache2/bin/apachectl stop
Note: The stop and start commands differ, based on the version and way of installation of Apache.
2. Install Nginx from source.
Download the nginx source file to your server.
bash# wget
Now you have to extract the tar file
bash# tar -zxvf nginx-0.6.34.tar.gz
Go to the nginx directory.
bash# cd nginx-0.6.34
We explicitly define the binary path because by default it will be installed in /usr/local/nginx/sbin/nginx . Its always better to put the binaries in standard locations. That is why
we configure it as follows.
bash# ./configure --sbin-path=/usr/local/sbin
Note: In your case some dependencies may have to satisfied. While doing the nginx install, I had to install pcre-devel, zlib-devel and openssl-devel. We will use yum for the install.
bash# yum install pcre-devel zlib-devel openssl-devel
Now make and make install.
bash# make
bash# make install
3. Lets start the nginx service
bash# /usr/local/sbin/nginx
4.Test the nginx installation
bash# lynx
It should show :
Welcome to nginx!
5.Configuring Apache and Nginx.
For Apache, we have to edit its configuration file, httpd.conf
Change Listen 80 to Listen :8080 and add a virtual host entry. It should look like the following.

Listen localhost:8080

ServerName localhost
DocumentRoot /usr/local/apache2/htdocs

Nginx is configured as below:
Stop the currently running nginx.
bash# kill `cat /usr/local/nginx/logs/`
Create a simple nginx configuration file nginx.conf in the following directory.
Add the following lines in the nginx configuration file using your favorite text editor.
I prefer good old’ VI editor.

bash# vi /usr/local/nginx/conf/nginx.conf
#nginx configuration
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log;
events {
worker_connections 256;
server {
listen 80;
# static files
location ~* ^.+.(jpg|jpeg|gif|png|ico|css|txt|js|htm|html)$ {
root /usr/local/apache2/htdocs;
# pass all else onto apache waiting at localhost:8080
location / {
proxy_pass http://localhost:8080;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

Now Apache is running on port 8080 and Nginx on 80.
Start the services, using the commands:
#/usr/local/apache2/bin/apachectl start
nginx handles all the connections in a number of processes as defined by worker_processes. We can start with 1, if needed we can increase it according to our needs.
If worker_connections is set to 256, Nginx can handle 256 X 1 = 256 concurrent connections. You can tweak the value of both to know what suits you the best.
Number of worker proccess can be calculated by
memory available for nginx / memory needed by worker = number of processes.
Note : Memory needed by worker can be seen using the top command.
Run the server for sometime and then change the configurations as needed to speed up your site. There are many other tweaks for the Apache-nginx combo. I will cover them in my next post, till then see ya and happy configuring.