Load-balancing APIs using Nginx with Example
Load balancing involves distributing API load to multiple backend servers efficiently. This task is done by a load balancer.
Load balancing allows your APIs to perform optimally even during peak loads, improves fault-tolerance and improves performance. Nginx started out primarily as a high-performance web server but in addition, to this, it is very well suited to be used as a reverse proxy and a load balancer for HTTP.
Most of the articles out there only show how to configure Nginx as a load balancer, which is fine. But in this article I will follow a different approach, we will see Nginx in action with an example.
We will set up two HTTP API servers run them on different ports and load balance them using Nginx.
Set up
We can very well perform this experiment on a local machine, but for this tutorial, I’ll be hosting everything on a DigitalOcean Droplet. You will get 100$ free credit on DigitalOcean if you signup via this link, I’ll get 25$.
First, we need to install Nginx.
sudo apt install nginx
Check if Nginx is running.
If it’s running then you will be able to see Nginx home page on your IP address.
Spin up API servers
Let’s spin up a couple of APIs on two different servers which will be load-balanced.
I’ll be creating APIs in Node.js. Coz that is the fastest way to spin up an API server. For this, we will need to have Node.js installed.
- Also Read: Build REST APIs in Node.js using Hapi.js
Create a new directory server1. This will be our API 1.
const app = express();
const servername = 'Ciphertrick Server 1'
app.get('/servername', (req, res)=>{
res.send(servername);
});
app.listen(3000, ()=>{
console.log('Listening on ', 3000);
});
It simply has an API that returns the server name.
Similarly, create another directory server2 and add the same API, but simply change the server name returned and the listening port.
const app = express();
const servername = 'Ciphertrick Server 2'
app.get('/servername', (req, res)=>{
res.send(servername);
});
app.listen(3001, ()=>{
console.log('Listening on ', 3001);
});
One very important thing to understand here is that we are creating two API server only for demo purposes, in the real world, you will have the same code base running on completely different VM’s with mostly identical configurations, and a separate Nginx server that sits on top of them distributing the load.
Now we need to run these two API servers in the background. For this, I’ll use the pm2 process manager.
cd ~/server1
pm2 start app.js --name=server1
cd ~/server2
pm2 start app.js --name=server2
Let’s see if our APIs are running…
Ciphertrick Server 1
[email protected]:~/server2# curl localhost:3001/servername
Ciphertrick Server 2
Okay so now we have everything in place except the load balancer. Let’s move in to do just that.
Setting up Nginx as Load Balancer with round-robin startegy
There are multiple strategies that can be used for load-balancing, we will start with the simplest, which is Round-Robin.
Open up the Nginx configuration file in the editor of your choice.
sudo nano default
Add upstream which will include the list of servers to load-balance.
server 127.0.0.1:3000;
server 127.0.0.1:3001;
}
Then under the server block comment root and add proxy_pass…
# Add index.php to the list if you are using PHP
# index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
proxy_pass http://backend;
#try_files $uri $uri/ =404;
}
Test out if the Nginx configuration is valid.
Reload Nginx.
Now, open up the API URL on your browser…
This should display Ciphertrick Server 1 on the first hit and if you reload the same page you should see Ciphertrick Server 2. This is Nginx load-balancing your APIs in a Round-Robin fashion.
Another way to test it out is by simply doing a curl from within the server.
[email protected]:/etc/nginx/sites-available# curl localhost/servername
Ciphertrick Server 1
//second request
[email protected]:/etc/nginx/sites-available# curl localhost/servername
Ciphertrick Server 2
Weighted Load Balancing in Nginx
Round-robin is the most basic of load-balancing strategies that Nginx provides and that is the strategy used by default unless any other is specified.
In weighted load-balancing, the load is distributed based on weights provided. Have a look below.
server 127.0.0.1:3000 weight=1;
server 127.0.0.1:3001 weight=2;
}
In the above configuration, Nginx will send twice as much traffic to Server 2 as compared to Server 1. The default weight is 1.
Sticky Load Balancing using Nginx
The above strategies work when we can randomly redirect requests. But in cases where we need to deal with user-session, we need to direct a particular user to the same server on every subsequent request. For this Nginx provides ip_hash strategy. In this strategy, Nginx redirects request based on the client’s IP address. Hence requests originating from same IPs are always redirected to the same server.
ip_hash;
server 127.0.0.1:3000;
server 127.0.0.1:3001;
}
Conclusion
Load balancing helps to improve the performance and resilience of your API servers, it mitigates risks of failures and betters risk governance. Nginx has come out to be the top web-server in the past few years but not only that it can very well perform other important tasks like reverse-proxy and load-balancing. In this article, we have learned how to setup Nginx as a load balancer with an example.
Keep Learning…
1 comment
Leave a Comment
hiiiii