AWS Horizontal Scaling and Load Balancer

Pre-requisite

To understand this blog, you should have basic knowledge of AWS EC2.

You can study EC2 from here.

Content of this blog

  1. What is Scaling and Why do we need it?
  2. Types of Scaling
  3. Load Balancer and Target Groups in AWS
  4. Tutorial of configuring Load Balancer in AWS
  5. Cleanup all resources

We will do everything with the hands-on tutorial on AWS Console.

What is Scaling and Why do we need it?

You often see that whenever someone launches their website on the internet and suddenly traffic increases, their website crashes. To prevent this we need to scale our system.

Scaling means we need to increase the specs of our EC2 instance (like increasing RAM, CPU, storage etc) or add more EC2 instances to handle the load.

You can relate it with the example of a mobile phone, when you buy a cheap mobile with less RAM and storage then your mobile hangs by using heavy games or a lot of applications at the same time. The same happens with the EC2 instance, when a lot of traffic comes at the same time then it also starts choking, that time we need to scale our system.

Types of Scaling

It is of 2 types:

  1. Vertical Scaling
  2. Horizontal Scaling

Vertical Scaling (Scaling Up/Down)

If we increase the specs (RAM, Storage, CPU) of the same machine to handle more load then it is called vertical scaling.

Ex: If our site has less traffic then we keep the “t2.micro” instance type and if the load increases we shift to the “t2.medium” machine.

This type of scaling is mostly used in SQL databases and also in stateful applications because it is difficult to maintain consistency of states in a horizontal scaling setup.

Horizontal Scaling (Scale Out/In)

If we add more machines and distribute the incoming load then it is called horizontal scaling.

In this setup, Clients don’t make requests directly to the server, instead, they send requests to the load balancer. The load balancer takes the incoming traffic and transfers it to the least busy machine.

Most of the time in the real world, we use horizontal scaling.

Below is the picture where you can see that 3 clients are making requests and the load balancer distributes the load in 3 EC2 instances equally.

Load Balancer and Target Groups in AWS

We have already studied the role of load balancers. It takes the incoming request and sends it to the least busy server.

AWS provides 3 types of load balancers:

  1. Application Load Balancer (ALB)
  2. Network Load Balancer (NLB)
  3. Classic Load Balancers (CLB)

We will only study ALB because it is the most used load balancer in the industries. NLB and CLB are rarely used.

Target Group

ALB doesn’t send the request directly to the EC2 instance. It sends the request to the target group. If we want this request to reach the EC2 instance, then we need to attach this target group to the EC2 instance.

Target Group TG1 is attached to the application load balancer, so it is sending all the incoming requests to the EC2 instances which has Target Group TG1 attached.

Features of ALB:

  • In one ALB, you can attach more than one target group.
  • ALB can route requests based on different criteria like host headers, path, source IP, etc.
    Ex: You can set a rule like this:
    /api/* forward to the Backend API target group
    /admin/* forward to the Admin Panel target group
    These are helpful when you have microservices and different microservices are deployed in different EC2 instances. Then you attach different target groups to it and configure it in ALB based on subdomains, params etc of the URL.
  • When you configure ALB then it gives you a domain name (not an IP address). Clients hit this ALB domain name on their browsers to access your website. As I told before, client don’t directly hit “http://<website_ip_address>:8080". Clients hit ALB and ALB will route their request to the least busy EC2 Instance.

Enough theory, now we will do practical of everything that we studied. Be ready with your AWS Console.

Tutorial of configuring Load Balancer in AWS

All requests with / will go in Target Group 1.

All requests with /product will go on Target Group 2.

Target Group 1 will be attached to 3 EC2 instances.

Target Group 2 will be attached to 2 EC2 instances.

Below is the code that we will deploy on each EC2 instance.

const express = require('express');
const app = express();

app.get("/", (req, res) => {
res.send("Welcome to AWS tutorial by Shivam Bhadani");
})

app.get("/product", (req, res) => {
res.send("This is Product Page");
})

app.get("/health", (req, res) => {
res.send("Everything is OK");
})

app.listen(8080, () => console.log("Sever is listening on Port 8080"))

You can get the above code here: https://github.com/shivam-bhadani/Simple-Nodejs-Server

Visualization Tutorial

  1. Launch 5 EC2 Instances with names:
    a) 1-home
    b) 2-home
    c) 3-home
    d) 1-product
    e) 2-product
    Target Group TG-Home is attached to 1-home, 2-home, 3-home instances.
    Target Group TG-Product is attached to 1-product, 2-product, 3-product instances.

All the requests that will come with / will go on either 1-home or 2-home or 3-home (whichever is least busy) and all the requests with /product will go on either 1-product or 2-product (whichever is least busy).

2. Create a load Balancer and attach TG-Home and TG-Product to this load balancer.

3. Do a simple configuration such that all the requests that will come with / will go on either 1-home or 2-home or 3-home instance (whichever is least busy) and all the requests with /product will go on either 1-product or 2-product instance (whichever is least busy).

Actual Tutorial

  1. Create 5 EC2 instances and run the above nodejs code on it.
    I will not show how to create EC2 Instance. We had already done it in our previous blog.
    Note: Don’t run your app by doing “node app.js” because if you close your SSH terminal or press CTRL + C then your app will be stopped. We don’t want to do this. Instead, we want to run our app forever even when we close our terminal.
    For this, do pm2 start app.js . Before this install pm2 on your machine by doing sudo npm install -g pm2 .

When you launch the instance then do the below thing in all 5 instances:
a) Do SSH
b) Run the following commands

sudo apt update
sudo apt install nodejs
sudo apt install npm
sudo npm install -g pm2
git clone https://github.com/shivam-bhadani/Simple-Nodejs-Server.git
cd Simple-Nodejs-Server
npm install
pm2 start app.js

2. Go to Target Groups (see on the left sidebar). Then click on “Create target group” button.

3. Give a name to this target group (I have given TG-Home, as told in the visualization tutorial). In the Protocol Port, make sure to give it the port in which your app is running on your EC2 instance. Our app is running on Port 8080 (you can see in the code).

4. Scroll down and in the health check, give any endpoint. I have made a separate route for health on “/health” (Look at the code). That’s why I have given /health. You can give default “/” also.
This route is to check whether our instance is healthy or not.
Then click on “Next” Button.

5. Select the EC2 instances which you want to attach on this TG-Home Target Group. I have selected 1-home, 2-home and 3-home.
Then, click on “Include as pending below” button. Then, click on “Create target group” button.

6. Now, Target Group TG-Home is created.

7. Follow Step 2 to 5 to create another target group with name TG-Product.

8. We have successfully created our both target groups and attached it to their respective instances.
We are done on Part 1 of our Visualization Tutorial.

9. Go to Load Balancers (see on the left sidebar). Then click on “Create load balancer” button.

10. Click on “Create” button under Application Load Balancer.

11. Give it a name (I have given shivam-alb-tutorial).

12. Scroll down and under Network mapping, select all three availability zones.

13. Attach a default Target Group. The request will go to this target group when no rule such as /product, /checkout etc matches.

14. Then finally click on “Create load balancer” button.

15. Now, our load balancer is created. You can see it gave us a DNS name (not IP Address). You can hit this DNS name on your browser and the request will be redirected to the target group.

16. Go to the DNS name from browser to get the response.

Oops, we can’t visit our site. Can you guess what mistake we did?

Answer: We haven’t configured the “security group”.
We have to do 2 things.
a) Allow all HTTP Traffic (inbound rule) on this load balancer’s security group
b) In the security group of EC2 instances, only allow traffic from load balancer.
In this way, people can only visit our site with load balancer DNS name and can’t directly hit the URL (http://<ip_address_of_instance>:8080) to get the response.

17. Copy the security group of ALB.

18. Go to security and click on security group of EC2 instance.

19. Click on Edit inbound rules

20. Add a Custom TCP on Port 8080 and select the security group of ALB (which you have copied).

In this way only ALB can access our EC2 instance.

21. Repeat steps 18 to 20 on all 5 instances.
Another way you can do: Create a security group with SSH and ALB allowed and attach this same security group to all 5 instances.

22. You can see in TG-Home target group, all instances came in healthy state.

23. Go to the security group of ALB and add “HTTP Port 80 allow anywhere rule”.

24. Now, again hit the DNS name of ALB in your browser. You will see the response.

You will not be able to hit http://<ip_address_of_instance>:8080 because it doesn’t have “allow anywhere” security rule. It only permits ALB traffic. So, you are hitting ALB and ALB routing your request to the respective instance which is very cool.

25. Now, we will set a rule that, if request comes with / will go TG-Home (and this target group is attached to 1-home, 2-home and 3-home instance) and request with /product will go to TG-Product (and this target group is attached to 1-product and 2-product instance).

Select the ALB then go to “Listeners and rules” on the footer. Then click on HTTP:80 Link.

26. Click on “Add rule” button.

27. Give any name to this rule. I have given Rule 1. Then click on “Next” button.

28. Click on “Add condition” button.

29. Select on what basis you want to define your rule. We will select “Path”.

30. Then give the path. We have given /product/* . Then click on Confirm button.

31. Select the target group. We are selecting TG-Product. So, all the request with /product will go to TG-Product target group. Then, click on “Next” button.

32. Give priority to this rule. I have given 1. This priority is self-explanatory that if paths are conflicting then which to give higher priority. Then click on Next.

33. Click on Create Button.

34. Now, our rule is created that all the request with /product will go on TG-Product target group.

35. You can hit the DNS of ALB on the browser and check the response.

In the real world, what we do is, configure rules such that requests with / go in Home microservice, requests with /product go on product microservice, requests with /payment go on payment microservice and so on.
I have shown the same thing in this tutorial. I hope you understand it.

Post a Comment

Previous Post Next Post