Load Balancing with Nginx

Nginx and Load Balancing

A lot can be said about Nginx (pronounced "engine X"). It is a web server that can be used as a reverse proxy or a load balancer. Basically a load balancer sits between the site visitor and the application servers (a pool of servers) acting like sort of cop directing traffic.

Load Balancing Algorithms on Nginx

There are different ways that traffic can be routed to your pool of servers:

  • Round Robin – Requests are distributed sequentially.
  • Least Connections – A new request is sent to the server with the fewest current connections to clients.
  • IP Hash – The IP address of the client is used to determine which server receives the request. Subsequent requests from the same IP will end at the same application server
  • Generic Hash - The server to which a request is sent is determined from a user‑defined key

There are other algorithms available for Nginx Plus which is the commercial version

Sample Load Balancer Setup

Sample Load Balancer Configuration

Using a round robin configuration:

http {
    upstream backend {
        server application.server.one;
        server application.server.two;
        server application.server.three backup;
    }

    server {
        location / {
            proxy_pass http://backend;
        }
    }
}

In this setup traffic will be routed this way assuming the visits are sequential:

  • Visitor one directed to application server one
  • Visitor two directed to application server two
  • Visitor three directed to application server one

In the event that both servers are unavailable traffic is directed to application server three. This allows for some high availability.

We can pass some extra headers in our location block for example X-Real-IP this will help our application servers to know the source traffic IP:

location / {
  proxy_pass http://backend;
  proxy_set_header        Host            $host;
  proxy_set_header        X-Real-IP       $remote_addr;
  proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
}

Sample Application Server Configuration

Suppose we are using Nginx on our Application servers we can get the source traffic IP and not the load balancer IP by using this sample configuration:

server {
    listen 80;
    .
    .
    location / {
        set_real_ip_from loadbalancer.server;
        real_ip_header X-Forwarded-For;
        .
        .
    }
}

Other considerations

What happens if our load balancer was to go down? How can we address having a single point of failure? How does our load balancer determine that an application server is unavailable not offline but for example if the server is returning an error 500? We will discuss possible solutions for that in future article.