Load Balancer in system design and node.js application .

system design

What is a Load Balancer?

A load Balancer is s a device that distributes network or application traffic across a number of servers in order to improve the availability and fault tolerance of a network. it is used to distribute incoming requests evenly across the servers in a group, allowing each server to handle a smaller number of requests at a time. This can improve the overall performance and scalability of the system.

Pros :

  1. Improved availability: By distributing incoming traffic evenly across a group of servers, a load balancer can help improve the availability of a network or application. If one server fails or becomes unavailable, the load balancer can redirect traffic to the other servers that are still functioning, allowing the network or application to continue functioning.

  2. Improved performance: Load balancers can help improve the performance of a network or application by distributing the workload evenly across multiple servers, allowing each server to handle a smaller number of requests at a time. This can help reduce response times and improve overall performance.

  3. Improved scalability: Load balancers can help improve the scalability of a network or application by allowing it to handle a larger volume of traffic. By distributing incoming traffic evenly across multiple servers, a load balancer can help ensure that the network or application can continue functioning smoothly even when there is a sudden increase in traffic.

  4. Improved security: Load balancers can help improve the security of a network or application by acting as a single point of entry for incoming traffic. This can help protect against attacks that target individual servers, as the load balancer can block or filter malicious traffic before it reaches the servers.

Cons:

  1. Additional cost: Load balancers can be implemented using hardware devices or software applications, and both options can be expensive. Hardware load balancers are typically more expensive than software-based solutions, but they may offer better performance and scalability.

  2. Complexity: Load balancers can be complex to set up and configure, especially in large and complex networks or applications. This can require specialized knowledge and skills, and it may involve additional time and resources.

  3. Single point of failure: In some cases, the load balancer itself can become a single point of failure for the network or application. If the load balancer fails or becomes unavailable, the entire system may be affected. To mitigate this risk, it is important to design the load balancer in a way that ensures high availability, such as by using multiple load balancers in a cluster or by implementing redundancy.

Category of Load Balancer :

  1. Hardware load balancers: These are physical appliances that are installed in the network and handle traffic distribution.

  2. Software load balancers: These are software programs that are installed on a server and handle traffic distribution.

  3. Cloud load balancers: These are load-balancing services that are provided by cloud providers, such as Amazon Web Services (AWS) or Microsoft Azure.

  4. Application load balancers: These are load balancers that are specifically designed to distribute traffic to applications, rather than servers or other resources. They are typically used in conjunction with microservices architectures and container-based deployments.

  5. Network load balancers: These are load balancers that operate at the network layer (layer 4 of the OSI model) and distribute traffic based on network-level metrics, such as IP address and port number.

  6. DNS load balancers: These are load balancers that operate at the domain name system (DNS) level and distribute traffic based on DNS records.

Example of Load Balacner using Cluster :

const express = require('express');
const cluster = require('cluster');
const { generateKeyPair } = require('crypto');

// Check the number of available CPU.
const numCPUs = require('os').cpus().length;

const app = express();
const PORT = 3000;

// For Master process
if (cluster.isMaster) {
console.log(`Master ${process.pid} is running`);

// Fork workers.
for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
}

// This event is firs when worker died
cluster.on('exit', (worker, code, signal) => {
    console.log(`worker ${worker.process.pid} died`);
});
}

// For Worker
else {
// Workers can share any TCP connection
// In this case it is an HTTP server
app.listen(PORT, err => {
    err ?
    console.log("Error in server setup") :
    console.log(`Worker ${process.pid} started`);
});

// API endpoint
// Send public key
app.get('/key', (req, res) => {
    generateKeyPair('rsa', {
    modulusLength: 2048,
    publicKeyEncoding: {
        type: 'spki',
        format: 'pem'
    },
    privateKeyEncoding: {
        type: 'pkcs8',
        format: 'pem',
        cipher: 'aes-256-cbc',
        passphrase: 'top secret'
    }
    }, (err, publicKey, privateKey) => {

    // Handle errors and use the
    // generated key pair.
    res.send(publicKey);
    })
})
}

using cmd node index.js

output

Master 16916 is running Worker 6504 started Worker 14824 started Worker 20868 started Worker 12312 started Worker 9968 started Worker 16544 started Worker 8676 started Worker 11064 started

using nginx :

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

// API endpoint
app.get('/', (req,res)=>{
    res.send("Welcome to GeeksforGeeks !");
})

// Launching application on several ports
app.listen(3000);
app.listen(3001);
app.listen(3002);
app.listen(3003);
  1. First, you will need to install NGINX on your server.

  2. Next, you will need to configure NGINX as a reverse proxy. To do this, you will need to create a configuration file in the /etc/nginx/conf.d directory. Here is an example configuration file that sets up NGINX as a load balancer for a Node.js application:

upstream app {
  server localhost:3000;
  server localhost:3001;
  server localhost:3002;
}

server {
  listen 80;
  server_name example.com;

  location / {
    proxy_pass http://app;
  }
}

In this example, NGINX is listening for incoming requests on port 80 and forwarding them to one of the three back-ends Node.js servers running on ports 3000, 3001, and 3002. The specific server that receives the request is chosen using the round-robin algorithm, which distributes requests evenly across the available servers.

  1. Once you have created the configuration file, you can start the NGINX service to begin load balancing your Node.js application:

    sudo systemctl start nginx

Load balancer interview questions :

  1. How would you design a load-balancing system for a web application?

    One approach to designing a load-balancing system for a web application would be to use a reverse proxy server, such as NGINX, to distribute incoming requests to a pool of back-end servers. The reverse proxy could be configured to use a load balancing algorithm, such as round-robin or least connections, to distribute the requests evenly across the available servers. The back-end servers could be configured to store session data in a shared cache, such as Redis, to allow for seamless failover if a server becomes unavailable.

  2. How would you handle server failures in a load-balancing system?

    • Health checks: The load balancer can periodically check the health of each server using a simple ping request or a more complex check that checks the server's response to a specific request. If a server fails the health check, it can be removed from the pool of available servers until it recovers.

    • Failover: If a server becomes unavailable, the load balancer can automatically fail over to another server. This can be done using a hot standby approach, where a standby server is already configured and ready to take over if needed, or a cold standby approach, where a new server is spun up and configured to take over if needed.

    • Redundancy: To further reduce the risk of downtime, you can use multiple load balancers in a redundant configuration, with each load balancer forwarding requests to a different set of back-end servers. This way, if one load balancer fails, the other load balancer can take over.

  3. How would you handle a sudden increase in traffic in a load balancing system?

    There are several approaches to handling a sudden increase in traffic in a load-balancing system:

    • Scaling up: If you are using a cloud-based load balancing system, you can scale up your system by adding more servers or resources to the pool of available resources. This can be done automatically using a scaling policy based on metrics such as CPU utilization or request rate.

    • Caching: You can use caching to reduce the load on your servers by storing frequently-accessed data in a cache, such as Redis or Memcached. This can help to reduce the number of requests that need to be handled by your servers.

    • Rate limiting: You can use rate limiting to limit the number of requests that your servers need to handle by rejecting or delaying requests that exceed a certain rate. This can help to prevent your servers from becoming overloaded.

  4. How would you design a load-balancing system for a microservices architecture?

    In a microservices architecture, you can use an application load balancer, such as the built-in load balancer provided by a container orchestration platform like Kubernetes, to distribute traffic to the individual microservices. The load balancer can be configured to use a load balancing algorithm, such as round-robin or least connections, to distribute the requests evenly across the available microservices. You can also use features such as health checks and circuit breakers to ensure that the load balancer is only forwarding traffic to healthy microservices.

Resources :

https://www.geeksforgeeks.org/how-to-create-load-balancing-servers-using-node-js/

https://nodejs.org/api/cluster.html

system design interview part one