Skip to main content

What is NGINX Load Balancing? A Beginner's Guide to Boosting Website Performance

11 minutes


Introduction

A load balancer is a device or a software application that distributes network traffic across multiple servers evenly. The main goals of a load balancer is to ensure reliability, improve performance, and enhance the availability of services.  

In this article, we will explore the Nginx Load Balancer, which is one of the most popular and effective load balancing options currently available in the market.

We'll also aim to grasp every load balancing technique employed by NGINX, ranging from the basic round robin approach to more sophisticated weighted strategies and complex IP hash techniques. This will give you a deeper understanding of the load balancing methods utilized by NGINX's load balancer, which could be beneficial for your unique setup.

What is NGINX Load Balancing?

NGINX (pronounced "engine-x") is not just a web server, though - it's also a reverse proxy server and, you guessed it, a load balancer. As a load balancer, NGINX plays a vital role in contemporary web applications, guaranteeing continuous accessibility and dependability by spreading out network or application traffic among several servers.

Why Care About NGINX Load Balancing?

Implementing a NGINX load balancer is like giving your website greater capabilities. Here’s why you should implement it in your setup?

  • Increased Performance: Your website stays up even faster when traffic is increasing by distributing traffic across multiple servers. No more slow load times!
  • High Availability: If one server goes down, NGINX can route traffic to healthy servers. 
  • Scalability: Scale at ease based on amount of network traffic.
  • Resource efficiency: Does not overwhelm servers by distributing network traffic fairly among them.
  • Enhanced Security: Using NGINX as a load balancer can make your backend servers less prone to direct Internet connections.

Configuring Nginx as a load balancer

Nginx implements load balancing through its upstream module. It sits in front of your backend server, receives the incoming request, and then decides which backend server should handle the request based on the algorithm you have chosen.

Let’s create a configuration file for the NGINX load balancer. By default, this load balancer will use a round-robin algorithm, distributing requests evenly across your upstream servers.

$ sudo vi /etc/nginx/sites-available/load-balancer.conf
#http {
  upstream backend {
     server 10.20.10.81;
     server 10.20.10.91;
     server 10.20.10.101;
  }
  server {
     listen 80;
     server_name myserver;
     location / {
         proxy_pass http://backend;
     }
  }
#}

Break this down into:

The upstream block defines a group of backend servers. We mentally called it the "backend.
The server block tells NGINX to listen on port 80 for requests to myserver.
The location block tells NGINX to forward all requests to our upstream backend.

Next, enable the configuration file by clicking a symbolic link to the load balancer configuration file in the sites-enabled folder.

$ cd /etc/nginx/sites-enabled
$ sudo ln -s ../sites-available/load-balancer.conf .

Back up or remove the default NGINX configuration file.

$ sudo mv /etc/nginx/sites-enabled/default /home/ubuntu

Make sure the line /etc/nginx/sites-enabled/*; is included in the NGINX configuration file /etc/nginx/nginx.conf.

http
{
       ...
       ...
       include /etc/nginx/conf.d/*.conf;
       include /etc/nginx/sites-enabled/*;
       ...
       ...
}

Check for any errors in the NGINX configuration file and restart the server.

$ sudo nginx -t
$ sudo systemctl restart nginx

Access your web application using either the server name or public IP of the load balancer, the request will be passed to one of the upstream server thereby load balancing your sites traffic.

$ curl http://myserver

That was running an NGINX load balancer on Ubuntu 22.04! The location of the above NGINX configuration file may be slightly different in other Linux distros such as CentOS, AlmaLinux or RHEL.

NGINX Load Balancing options

Nginx offers many load balancing algorithms depending on your needs. It is important to choose the right algorithm based on the type of upstream server required by your application.

There are 5 major load balancing schemes available in the open-source NGINX version, with additional options included in NGINX Plus. Let’s get into these:

Round Robin: A standardized algorithm

We’ll start with an old, reliable load balancing system: Round Robin. It's the default option in Nginx, and for good reason - it's simple, predictable, and gets the job done.

Here the requests are spread out evenly around the upstream servers in a round robin shape. That's essentially what Round Robin does with incoming requests and your upstream servers.

Pros:

  • Simple to understand and implement.
  • Ensures a fair distribution of requests across all servers.
  • It works best when all your servers have the same capacity.

Cons:

  • It does not show server load or response time.
  • If requests vary widely in complexity, they may lead to uneven distribution.
  • The load balancer we used in the previous example uses a round-robin approach under the hood and distributes requests equally among the three upstream servers.  

Note: While Round Robin is great for starters, check your server metrics. If you find that one server is consistently behind, it may be time to look for other algorithms.

Least connection: Server load optimization

Lets discuss about the Least Connections algorithm. While Round Robin means to treat all the upstream servers in an equal manner, Least Connections passes the request to the specific upstream server that is least busy or Handling the least number of connections.

In simple terms when a new request comes in then Nginx sees which upstream server has the least connections to serve that new request and it goes straight to the least connected server. 

Pros:

  • Prevent overloading of any one server.
  • It adapts well to different server capabilities.
  • Great for handling requests with different processing times.

Cons:

  • It’s a little harder than round robin.
  • It may not be good if your connections are generally very short-lived.
  • Least Connections really shines in situations where your requests vary greatly in complexity or duration.

Least Connections really shines in scenarios where your requests vary significantly in complexity or duration. For example, you can use it in applications where some API calls took milliseconds while others could run for several seconds. The difference was like night and day compared to Round Robin!

Here's how you'd set it up in Nginx:

#http {
 upstream backend {
    least_conn;
    server 10.20.10.81;
    server 10.20.10.91;
    server 10.20.10.101;
 }

 server {
    listen 80;
    server_name myserver;
    location / {
        proxy_pass http://backend;
    }
 }
#}

The least_conn directive in the upstream block is all it takes to switch from Round Robin to Least Connections. Simple, yet powerful!

Note: While Least Connections is often more efficient than Round Robin, it's not a silver bullet. If your servers have vastly different processing power, you might want to combine this with weighted load balancing.

 

 

IP Hash: Ensuring Session Persistence

Alright, let's dive into one of the popular NGINX load balancing methods: IP Hash. This one is a bit different from previous algorithms, and it solves a pretty specific problem of session persistence. 

In IP hash, a hashing key from the client's IP address is used to select an upstream server and consistently maps the same IP to the same server for subsequent connections, unless that server is not available.  

Pros:

  • Ensures session persistence.
  • Great for applications that require state to be maintained.
  • Can improve cache hit rates on backend servers.

Cons:

  • May lead to uneven distribution if you have a lot of traffic from a single IP (think corporate networks).
  • It doesn't account for varying server capacities.

IP Hash is your best friend when dealing with applications that need to maintain state or session data.

Here's how you'd implement it in Nginx:

#http {
upstream backend {
   ip_hash;
   server 10.20.10.81;
   server 10.20.10.91;
   server 10.20.10.101;
}

server {
   listen 80;
   server_name myserver;
   location / {
       proxy_pass http://backend;
   }
}
#}

Just add that ip_hash; line, and you're good to go!

If you need to take a server out for maintenance but don't want to disrupt existing sessions, you can mark it as "down" in the configuration:

upstream backend {
   ip_hash;
   server 10.20.10.81;
   server 10.20.10.91;
   server 10.20.10.101 down;
}

This way, new connections will be distributed between the server1 and server2, but existing sessions on server3 won't be disrupted.

Note: While IP Hash is great for session persistence, it's not always the best choice for even load distribution. It's all about picking the right algorithm for the job!

Weighted Load Balancing: Fine-tuning Traffic Distribution

Weighted weight balancing is not a stand-alone algorithm, but rather a way to fine-tune other methods such as round-robin or minimal combinations. It is based on the concept that not all servers have the same amount of resources(CPU, Memory). Maybe you have a powerful server that can handle twice the load of your others or a smaller one that you don’t want to worry too much about.

In this method, you assign a weight to each server in your upstream block. The higher the weight, the more connections that server receives.

Pros:

  • Resource efficiency: You get the most out of your infrastructure by sending more traffic to more powerful servers.
  • Gradual server selection: When adding a new server, you can start with a lower load and gradually increase it.
  • Traffic size: You can use weights to control the amount of traffic to different parts of your application.

Cons:

  • Complexity: It requires more thought and management than simple round-robin algorithm.
  • It’s not always ideal: In some cases, an overloaded server can end up with more connections than it can effectively handle, while a less loaded server stays idle.
    Possible causes of imbalance: If the load is not configured properly, you can overload some servers while underusing others.

Here's an example of how you'd configure weighted load balancing:

#http {
upstream backend {
  server 10.20.10.81 weight=3;
  server 10.20.10.91 weight=2;
  server 10.20.10.101 weight=1;
}

server {
  listen 80;
  server_name myserver;
  location / {
      proxy_pass http://backend;
  }
}
#}

In this configuration, server1 will have 3, server2 2, and server3 1 for every 6 requests.

Weighted load balancing is super flexible and can be combined with other methods.

Remember, the goal is to distribute the load efficiently while using your resources best. With weighted load balancing, you've got a powerful tool to do just that.

Note: Don't go overboard with precise weights. Stick to simple ratios like 1:2:3. It makes it easier to reason about the traffic distribution and adjust as needed.

Least Time: Balancing Based on Response Time

Let's look at the one of the more sophisticated load balancing methods Nginx offers: the Least Time algorithm. 

Least Time takes into account not just the number of active connections (like Least Connections does), but also the response time of each server. It's available in Nginx Plus and comes in two flavors: least_time header and least_time last_byte.

Here's the breakdown:

least_time header: Sends the request to the server with the lowest average time to receive the response header.
least_time last_byte: Chooses the server with the lowest average time to receive the full response.

Least Time is a powerful tool in your load balancing arsenal. If you're dealing with servers of varying capabilities or network conditions, and you're willing to spring for Nginx Plus, it's definitely worth considering!

Pros:

  • Optimizes for actual server performance, not just connection count.
  • Can significantly improve response times for end-users.
  • Adapts well to varying server capabilities and network conditions.

Cons:

  • Only available in Nginx Plus (the commercial version).
  • Slightly more complex to set up and monitor.

Here's how you'd configure it:

#http {
upstream backend {
 least_time header;
 server 10.20.10.81;
 server 10.20.10.91;
 server 10.20.10.101;
}

server {
 listen 80;
 server_name myserver;
 location / {
     proxy_pass http://backend;
 }
}
#}

Just replace header with last_byte if you want to use that version instead.

Note: While Least Time can be super effective, it's not a magic bullet. If one server starts responding faster simply because it's not doing any work, you might end up overloading it. That's why it's crucial to monitor your servers and adjust as needed.

 

 

Random: Adds unpredictability to weight distribution

Let’s talk about the wild card of load balancing algorithms: The random method. This is exactly what it looks like - Nginx randomly chooses a server for each incoming request. For each new request, Nginx randomly selects a server from the pool of upstream servers.

It’s simple, requires no governance, and can work well in large deployments but can lead to misallocation in the short term, especially random load balancing with small server pools shines in situations where you have a large number of servers with the same capacity in the same

Pros:

Ease of Use: Simple and easy to understand.
Even distribution (over time): Given a large number of requests, the distribution tends to be even across servers.
Low overhead: Routing requires minimal computing resources and works well with microservices.

Cons:

Short-term Imbalances: Over short periods, some servers may receive significantly more or fewer requests than others.
Unpredictable Performance and uneven resource utilization: The randomness can lead to inconsistent response times for users and might not fit well for servers with different capacities.
Session Stickiness Issues: Without additional configuration, it doesn't guarantee that a user's subsequent requests will go to the same server.

Here's how you'd set it up:

#http {
upstream backend {
 random;
 server 10.20.10.81;
 server 10.20.10.91;
 server 10.20.10.101;
}

server {
 listen 80;
 server_name myserver;
 location / {
     proxy_pass http://backend;
 }
}
#}

Just add that random; directive, and you're ready to use random algorithm!

Note: Combine random and weighted load balancing algorithm for greater controllability.

Factors to consider when choosing a load balancing algorithm

We’ve covered many algorithms, but how do you choose the right one? Here are some key things to keep in mind:

Your application type:

  • Stateful apps benefit from IP Hash.
  • APIs with different response times may use fewer connections or less time.

Server capacity and resources:

  • Such servers? Round Robin or Random can do the trick.
  • A mixed bag of servers? Consider weighting methods.

Traffic and user behavior:

  • A lot of people reusing it? IP Hash can be your friend.
  • An unexpected spike in traffic? Least Connections can also help make things better.

Scalability Requirements:

  • If you add/remove servers frequently? It is easy to handle random or round-robin.
  • Need to use fine grains? Weighted methods offer greater flexibility.

Remember, there is no one-size-fits-all solution. The best approach is generally to start simple (as in Round Robin) and then adjust based on real-world performance data. Set up a test environment and test different algorithms. Check your server’s load, response time, and error rate. The data will tell you what works best for your specific use case.

 

 

Conclusion:

We've covered a lot of ground in our journey through Nginx's load balancing algorithms. From the straightforward Round Robin to the more complex Least Time, each method has its own strengths and ideal use cases.

Remember, choosing the right load balancing algorithm is like picking the perfect tool for a job. Round Robin might be your trusty hammer, while IP Hash could be your precision screwdriver. The key is understanding your specific needs and how each algorithm can address them.

Don't forget the importance of monitoring and testing. The best load balancing setup is one that's continually refined based on real-world performance data. Keep an eye on those server metrics, response times, and error rates!

fivestar_rating
No votes yet
Comments