Let’s say that you have a nice idea for a website and you want to host it somewhere to make it available to the users. To do this, you put your website on a server somewhere on the cloud. Then, you purchase a domain name and you redirect all the requests to this server. But you soon realize that you are getting too much traffic, and that your server won’t be able to handle all of it by itself. So you go ahead and get three more servers. Now you want make sure all your servers share the load in a nice way. How will you do that? We would like to avoid the situation where one of the servers is getting all the traffic, and the remaining servers are getting a small amount. That wouldn’t serve our purpose here! So how we do we handle this?
What exactly is load balancing?
The process of distributing the load in a controlled manner is called load balancing. When a lot of people visit the websites, you want to make sure you can handle all of that without crashing your servers. A website going down is probably one of the worst things that can happen to it! Load balancing is a useful mechanism to distribute incoming traffic around several capable servers. Also, by distributing the workload to several machines, we can increase fault tolerance and stability. It is a commonly used technique for optimizing resource utilization, maximizing throughput, and reducing latency.
What is Nginx? How does it help here?
Before we start, let’s clarify the pronunciation of the word. It’s pronounced as “Engine X”! Nginx is a reverse proxy server that can be used as a load balancer and caching server. Basically, for our blog post, let’s just say that Nginx is a beautiful piece of software that can handle load balancing really well. It’s been built in a way such that it can handle an extremely large number of simultaneous connections in a very efficient manner.
There are a couple of different ways to handle load balancing in nginx. The round robin algorithm for load balancing sends visitors to one of a set of IP addresses in a round robin fashion. The least-connected method sends every new request to the server with the least number of active connections. IP-hash method uses a hash-function to determine what server should be selected for the next request based on the client’s IP address.
How do I set up a web server to use nginx?
Okay, now that we have some background, let’s go ahead and see how to set up a simple web server using nginx. To have some practical insights, I’m going to assume you have a couple of servers somewhere on the cloud. If not, you can just use the AWS free tier. Go ahead and launch two AWS micro instances. Let’s name them “first_instance” and “second_instance”.
Open up your terminal and SSH into the first instance by typing the following:
$ ssh -i ~/.ssh/<FILENAME>.pem ubuntu@IP-ADDRESS
Replace IP-ADDRESS with the appropriate values. You can just check your EC2 dashboard to get it.
Now that you are inside the instance, let’s go ahead and set up a simple server that’s going to serve a simple html file. Create a folder called “first” in your home directory. Navigate to that folder and create a file called “index.html”. Type “This is the first instance” in that file and save it. You can now host a simple server by typing the following:
$ python -m SimpleHTTPServer
This should start the server on port 8000. If you go to “http://IP-ADDRESS” on your browser, you should see “This is the first instance” being displayed.
Create a second AWS instance and repeat the above steps. The only difference is that you need to write “This is the second instance” in the index.html file. Once you confirm that both the servers are active, you can proceed.
I don’t see any nginx yet. Where is it?
Okay we are almost there! We just created two servers and we need to put nginx in front of them to handle load balancing. Create a third AWS instance and name it “nginx_instance”. SSH into it and do the following:
$ sudo apt-get update $ sudo apt-get install nginx
Navigate to “/etc/nginx/sites-available” in your terminal. Copy the file “default” to a safe location and then open the file “/etc/nginx/sites-available/default”. You will need to open it in sudo mode because it’s read-only, and so you won’t be able to modify it if you don’t use sudo. Delete whatever you see there and add the following lines:
http { upstream mywebapp { server ec2-<IP-OF-THE-FIRST-INSTANCE>.<SERVER-REGION>.compute.amazonaws.com:8000 weight=1; server ec2-<IP-OF-THE-SECOND-INSTANCE>.<SERVER-REGION>.compute.amazonaws.com:8000 weight=1; } server { listen 80; location / { proxy_pass http://mywebapp; } } }
Once it’s done, go ahead and type the following in your terminal on the instance “nginx_instance”:
$ sudo nginx -t
This will check if there are any syntax errors in your config. If nothing is wrong, it will display a success message. Now go ahead and start nginx by using:
$ sudo service nginx start
That’s it! If you visit “http://IP-OF-THE-NGINX-INSTANCE” from your browser, you should see “This is the first instance” being displayed. If you refresh it, it should display “This is the second instance”. This means that nginx is distributing the load between the two servers equally. You can distribute the load unequally using the “weight” keyword. The usage of this keyword is shown in the code above
This is just a demonstrative example. Instead of the simple server that we have right now, you can host any web app you want and it will work just fine. As long as you specify the right parameters in the nginx config file, you should be good to go.
———————————————————————————————————