Skip to content

HTTP Load Balancing with Nginx

homepage-banner

Introduction

As web traffic grows and applications become more complex, load balancing becomes a critical component for ensuring the availability and scalability of web applications. In this blog post, we will explore how to use Nginx as a load balancer for HTTP traffic.

Proxying HTTP Traffic to a Group of Servers

To begin using NGINX Plus or NGINX Open Source for load balancing HTTP traffic to a server group, you must first define the group using the upstream directive. This directive is placed in the http context.

Servers in the group are configured using the server directive (not to be confused with the server block that defines a virtual server running on NGINX). For instance, the following configuration defines a group named backend consisting of three server configurations (which may resolve to more than three actual servers):

http {
    upstream backend {
        server backend1.example.com weight=5;
        server backend2.example.com;
        server 192.0.0.1 backup;
    }
}

To send requests to a server group, you can specify the name of the group in the proxy_pass directive. For other protocols like FastCGI, Memcached, SCGI, or uWSGI, use the corresponding directives like fastcgi_pass, memcached_pass, scgi_pass, or uwsgi_pass. The following example shows how a virtual server running on NGINX passes all requests to the backend upstream group defined in the previous example:

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

The following example shows how to proxy HTTP requests to the backend server group, which includes three servers. Two of the servers run instances of the same application, while the third is a backup server. Because no load-balancing algorithm is specified in the upstream block, NGINX uses the default algorithm, Round Robin.

http {
    upstream backend {
        server backend1.example.com;
        server backend2.example.com;
        server 192.0.0.1 backup;
    }

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

Load Balancing Algorithms

While Nginx’s default round-robin algorithm works well in most cases, there are other load balancing algorithms available. These algorithms can be useful in certain situations where you need more control over how requests are distributed.

Choosing a Load-Balancing Method

NGINX Open Source supports four load-balancing methods, and NGINX Plus adds two additional methods:

  1. Round Robin – Requests are distributed evenly across the servers, with server weights taken into consideration. This method is used by default (there is no directive for enabling it):

    upstream backend {
       # no load balancing method is specified for Round Robin
       server backend1.example.com;
       server backend2.example.com;
    }
    
  2. Least Connections – A request is sent to the server with the least number of active connections, again with server weights taken into consideration:

    upstream backend {
        least_conn;
        server backend1.example.com;
        server backend2.example.com;
    }
    
  3. IP Hash – The server to which a request is sent is determined from the client IP address. In this case, either the first three octets of the IPv4 address or the whole IPv6 address are used to calculate the hash value. The method guarantees that requests from the same address get to the same server unless it is not available.

    upstream backend {
        ip_hash;
        server backend1.example.com;
        server backend2.example.com;
    }
    

    If one of the servers needs to be temporarily removed from the load‑balancing rotation, it can be marked with the down parameter in order to preserve the current hashing of client IP addresses. Requests that were to be processed by this server are automatically sent to the next server in the group:

    upstream backend {
        server backend1.example.com;
        server backend2.example.com;
        server backend3.example.com down;
    }
    
  4. Generic Hash – The server to which a request is sent is determined from a user‑defined key which can be a text string, variable, or a combination. For example, the key may be a paired source IP address and port, or a URI as in this example:

    upstream backend {
        hash $request_uri consistent;
        server backend1.example.com;
        server backend2.example.com;
    }
    

    The optional consistent parameter to the hash directive enables ketama consistent‑hash load balancing. Requests are evenly distributed across all upstream servers based on the user‑defined hashed key value. If an upstream server is added to or removed from an upstream group, only a few keys are remapped which minimizes cache misses in the case of load‑balancing cache servers or other applications that accumulate state.

  5. Least Time (NGINX Plus only) – For each request, NGINX Plus selects the server with the lowest average latency and the lowest number of active connections, where the lowest average latency is calculated based on which of the following parameters to the least_time directive is included:

    • header – Time to receive the first byte from the server
    • last_byte – Time to receive the full response from the server
    • last_byte inflight – Time to receive the full response from the server, taking into account incomplete requests
    upstream backend {
        least_time header;
        server backend1.example.com;
        server backend2.example.com;
    }
    
  6. Random – Each request will be passed to a randomly selected server. If the two parameter is specified, first, NGINX randomly selects two servers taking into account server weights, and then chooses one of these servers using the specified method:

    • least_conn – The least number of active connections
    • least_time=header (NGINX Plus) – The least average time to receive the response header from the server (https://nginx.org/en/docs/http/ngx_http_upstream_module.html#var_upstream_header_time)
    • least_time=last_byte (NGINX Plus) – The least average time to receive the full response from the server (https://nginx.org/en/docs/http/ngx_http_upstream_module.html#var_upstream_response_time)
    upstream backend {
        random two least_time=last_byte;
        server backend1.example.com;
        server backend2.example.com;
        server backend3.example.com;
        server backend4.example.com;
    }
    

    The Random load balancing method should be used for distributed environments where multiple load balancers are passing requests to the same set of backends. For environments where the load balancer has a full view of all requests, use other load balancing methods, such as round robin, least connections and least time.

Note: When configuring any method other than Round Robin, place the corresponding directive (hash, ip_hash, least_conn, least_time, or random) above the list of server directives in the upstream {} block.

Conclusion

Nginx is a powerful and flexible tool for load balancing HTTP traffic. Its simple configuration and efficient algorithms make it a popular choice for web developers and system administrators. By using Nginx as a load balancer, you can ensure the availability and scalability of your web applications.

Reference

  • https://docs.nginx.com/nginx/admin-guide/load-balancer/http-load-balancer/
Leave a message