The general idea behind using a load balancer is that it allows you to distribute the HTTP traffic across many nodes, i.e. Nginx is conncted to multiple backend servers (application servers ). Nginx handles all incoming requests, distributes them across the backend se" /> The general idea behind using a load balancer is that it allows you to distribute the HTTP traffic across many nodes, i.e. Nginx is conncted to multiple backend servers (application servers ). Nginx handles all incoming requests, distributes them across the backend se" /> \n The general idea behind using a load balancer is that it allows you to distribute the HTTP traffic across many nodes, i.e. Nginx is conncted to multiple backend servers (application servers ). Nginx handles all incoming requests, distributes them across the backend se" />
Loader

Nginx Load Balancing

Nginx Load Balancing

The general idea behind using a load balancer is that it allows you to distribute the HTTP traffic across many nodes, i.e. Nginx is conncted to multiple backend servers (application servers ). Nginx handles all incoming requests, distributes them across the backend servers that actually fulfill the request, fetches the response, and sends it back to the client.

Load balancing can improve performance in many ways :

  • SSL termination: SSL encryption/decryption will be managed by the load balancer. This reduces SSL management overhead as the traffic between load balancer and back-end servers is in HTTP.
  • Caching :Nginx load balancer can be used to save responses received from the backend servers. This improves response time because Nginx responds to clients with the cached responses without forwarding requests to the backend servers.
  • High Availability : Using a load balancer eliminates the problem of single point of failure, i.e. if one of the back-end server becomes down, the load balancer will forward all requests to any other available server.
  • Scalability : As the load on servers increases, new servers can be easily added to be able to handle  more load on the servers .

Configuring Nginx as a load balancer requires two essential modules:

Upstream module: It is used to define a list of the backend servers. The servers that the load will be distributed across them . The upstream block is placed into http context.

FastCGI module: It is responsible for passing requests to the backend servers.

Both modules are built in Nginx core.

Example configuration:
Configuring upstream block

upstream apps {
           server backend1.com;
           server backend2.com;
        }

Any number of backend servers can be added in this block.
configuring fastcgi and connecting to the upstream block “apps”

location ~ \.php$ {
           fastcgi_index index.php;
           include fastcgi_params;
           fastcgi_pass apps;
        }

Any request to fastcgi will be forwarded to one of the backend servers. This configuration may cause a serious security problem because it may allow arbitrary code execution. This may happen because the default PHP configuration tries to guess which file to be executed if the requested file wasn’t found.
For example, if the requested URL was /www.example.com/image.jpg/test.php which does not exist, but if /www.example.com/image.jpg does. The PHP interpreter will execute /www.example.com/image.jpg. It may contain an embedded PHP code which may cause a problem.
In order to avoid this problem edit php.ini file, set cgi.fix_pathinfo= 0 to make php interpreter only try to execute the actual file given and do nothing if the file wasn’t found.

# vi /etc/php5/fpm/php.ini
 cgi.fix_pathinfo=0

There are 3 load balancing mechanisms supported by Nginx :

Round Robin : Using RR algorithm Nginx distribute the load equally across the backend servers. This is the default method if load balancing method is not specifically configured, this method works fine in most cases but it is preferred if the backend servers have similar capabilities such as equal in CPU, memory, etc.

Example configuration

upstream apps {
            server backend1.com;
            server backend2.com;
        }

creating a simple test page for each backend server in order to know which server processed the request

#for ((i=1;i<=5;i++)); do curl -v "LoadBalancer/test.php"; done
This is backend2
This is backend1
This is backend2
This is backend1
This is backend2

IP hash :this option ensures that the same client will be served by the same backend server. Nginx will distribute requests based on client’s IP address because client’s IP address is used as a hash key to determine which backend server should be selected to serve the client’s request. this means the subsequent client’s requests will be served by the same backend server .there is no guarantee that this will happen by the other methods. this method is preferred when the applications require stickiness between a client and a server (session persistence ) otherwise the application session will be broken and may cause a problem for the client.

To configure Nginx to use ip hash method for load balancing just add “ip_hash” directive in the upstream block as shown

upstream apps {
            ip_hash;
            server backend1.com;
            server backend2.com;
                }
#for ((i=1;i<=5;i++)); do curl -v "LoadBalancer.com/test.php"; done
This is backend1
This is backend1
This is backend1
This is backend1
This is backend1

least connected :enabling this option forces the load balancer to select the backend server that has the least number of active connections at this moment.
This method is preferred if some requests take longer time than others to complete, so the load is distributed more fairly across the backend servers because Nginx will pass the request to the server with the least number of active connection and won’t overload the busy server with more requests.
To configure Nginx least connected load balancing we must add least_conn directive in our upstream block as follows

upstream apps {
                  least_conn;
                  server backend1.com;
                  server backend2.com;
                   }

The server directive can be configured with several parameters down, backup, weight, max_fails, fail_timeout.

down : marks the backend server as unavailable, i.e. the server is no longer used, this option can be used with ip hash only .

backup : marks backend server as a backup server ,it means the server will receive requests for the load balancer only if all primary servers are unavailable

weight : sets the weight of a backend server for example if you set the weight of the backend1 server to 2 , it means no. of requests for backend1= 2 * no. of request for backend2

upstream apps {
          server backend1.com weight=2;
          server backend2.com
              }

max_fails : sets the number of communication failures with the server that should happen in the duration set by the fail_timeout parameter to consider the server unavailable for a duration also defined by the fail_timeout parameter

fail_timeout : defines the duration within which max_fails should occur.

Simple Scenario

Using nginx as a HTTP load balancer to distribute PHP requests across the backend servers and to serve static content , this configuration improves the performance of the web application .

Configuring Upstream module to use round robin load balancing method

upstream apps {
             server backend1.com:9000;
             server backend2.com:9000;
             server unix:/var/run/php5-fpm.sock backup;
              }

Note that using backup keyword to make the load balancer only works when both apps are down and not responding. We should then reference the module further on in the configuration.

server {
           listen 80;
           root /var/www/;
           index index.php index.html index.htm;
           server_name LoadBalancer.com;
           location / {
           try_files $uri $uri/ /index.php;
           }
           location ~ \.php$ {
             fastcgi_index index.php;
                    include fastcgi_params;
                    fastcgi_pass apps;
                    }
             }