Nginx load balancing

Load balancing between multiple applications, backends, and servers is part of the process of optimizing resources, improving performance, and fault tolerance of the service.

Nginx as a load balancer

This web server is considered one of the most popular and productive solutions because it has the broadest functionality and flexibility when configuring. So Nginx is often used for load balancing.

There are several approaches and implementations, but first check the availability of the module ngx_http_upstream_module:

# nginx -v

If it is missing, then you will have to rebuild Nginx by adding this module. After that, you can begin to configure the webserver. To enable balancing, add the upstream directive (http section) to the Nginx configuration file:

upstream backend  {
  server backend1.somesite.com;
  server backend2.somesite.com;
  server backend3.somesite.com;
}

Now you need to specify the redirection of the necessary group:

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

In addition, Nginx supports additional parameters and load balancing methods.

Choosing a balancing method

Nginx offers several load balancing methods.

Round-robin

By default, the webserver distributes requests evenly between backend’s (but taking into account weights). This is a standard method in Nginx, so there is no inclusion directive.

least_conn

Requests are first sent to the backend with the least number of active connections (but taking into account weights):

upstream backend {
    least_conn;

    server backend1.somesite.com;
    server backend2.somesite.com;
}

Hash and IP hash

Using this method, you can create a kind of persistent connection between clients and backends. For each request, Nginx calculates a hash that consists of text, web server variables, or a combination of them, and then maps it to the backends:

upstream backend {
   hash $scheme$request_uri;

   server backend1.somesite.com;
   server backend2.somesite.com;
   server backend3.somesite.com;
}

IP hash only works with HTTP, this is a predefined option in which the hash is calculated by the client’s IP address:

upstream backend {
   ip_hash;

   server backend1.somesite.com;
   server backend2.somesite.com;
   server backend3.somesite.com;
}

Backend weight

If certain backends on the stack are more powerful than others, then weights come in handy:

upstream backend {
    server backend1.somesite.com weight=10;
    server backend2.somesite.com weight=5;
    server backend3.somesite.com;
    server 192.0.0.1 backup;
}

In this example, out of every 16 requests, the first backend will process 10, the second 5, and the third 1. In this case, the backup server will receive requests only if the three main backends are unavailable.

Monitoring

If Nginx believes that the backend server is unavailable, it temporarily stops sending requests to it. Two directives are responsible for this:

  • max_fails — sets the number of failed connection attempts, after which the backend is considered unavailable for a certain time;
  • fail_timeout — time during which the server is considered unavailable.

The parameters look like this:

upstream backend {                
    server backend1.somesite.com;
    server backend2.somesite.com max_fails=3 fail_timeout=30s;
    server backend3.somesite.com max_fails=2;
}

Conclusion

Choosing the appropriate balancing method will make it possible to more evenly distribute the load. Do not forget about backend weights, monitoring, and server fault tolerance.

Related Post