How to set Nginx as loadbalancer for Apache or Tomcat

You can use Nginx as a loadbalancer as a front end in your web application.

For example, if your application is running on Apache (or Tomcat), you can set up an accountable second instance of the enterprise application on Apache (or Tomcat) on a different server.

And then, you can put Nginx on the front end, which will balance the load between the two Apache servers (or Tomcat or JBoss).

If you are new to Nginx, it is important to understand the difference between Nginx vs Apache and the Nginx architecture.

Nginx supports the following three types of load balancing:

  1. round-robin is the default type for Nginx, which uses a typical round robin algorithm to decide where to route the incoming request
  2. least-connected – as the name suggests, an incoming request will be sent to the server that has the least connection.
  3. ip-hash – This is useful when you want persistence, or connect the connection of an incoming request. In this type, the client’s IP address is used to decide which server the request should be directed to.

1. Define upstream and proxy_pass in Nginx config file

For load balancing, you need to add two things to your Nginx configuration file:

  1. upstream
  2. proxy_pass

First, upstream: Provide a unique name (could be the name of your application) and a list of all servers that will load balance Nginx.

In the following example, “crmdev” is the name upstreamwhich is the name of the application that is running as an individual Apache server (101.1 and 102.2 as shown below). Instead of “crmdev”, you can specify whatever you like.

Note: upstream must be defined within the “HTTP” context of Nginx.

upstream crmdev {
    server 192.168.101.1;
    server 192.168.101.2;
}

Note: If individual servers are running on a different port (except port 80), then specify the port number as shown below in the upstream

upstream crmdev {
    server 192.168.101.1:8080;
    server 192.168.101.2:8080;
}

Second, proxy_pass: Specify the unique name of the upstream that was defined in the previous step as proxy_pass inside your “Location” section, which will be according to the “server” section, as shown below.

server {
  listen 80;
  
  location / {
    proxy_pass http://crmdev;
  }
}

Note: In this example, Nginx itself listens on port 80, as shown above, using the listen parameter.

Note that you can also use proxy_pass to configure Nginx as a reverse proxy for Apache / PHP.

2. Define upstream and proxy_pass in default Nginx config file

Note: Generally, the above should be in accordance with HTTP or HTTPS as shown below.

http {
  upstream crmdev {
   server 192.168.101.1:8080;
   server 192.168.101.2:8080;
  }

  server {
      listen 80;

      location / {
          proxy_pass http://crmdev;
      }
  }
}

But, if you are using default.conf that comes with the default nginx.conf file, you do not need “HTTP” as it is already defined in the HTTP context.

Note: For HTTPS, replace the “HTTP” context (on the 1st line above) with HTTPS. Also, on the proxy_pass line, use https: // {-your-upstream-name-}

In this case, if you use “HTTP” as shown above, you may receive the following HTTP directive is not allowed error message:

Starting nginx: nginx: [emerg] "http" directive is not allowed here in /etc/nginx/conf.d/default.conf:1

This is a copy of the default.conf file where I added an upstream at the top (no HTTP) and then commented out the default location and added the new location using proxy_pass.

# vi /etc/nginx/conf.d/default.conf
upstream crmdev {
    server 127.0.0.1:4080;
    server 127.0.0.1:7080;
}
server {
  listen       3080;
  server_name  localhost;
  
  #location / {
  #    root   /usr/share/nginx/html;
  #    index  index.html index.htm;
  #}
  
  location / {
    proxy_pass http://crmdev;
  }
..
..
}

3. Installation by algorithm to the least active Nginx for load balancing

In this algorithm, the incoming request is sent to the server that has the least number of active connections.

To do this, add the “least_conn” keyword at the top of the upstream as shown below.

upstream crmdev {
    least_conn;
    server 192.168.101.1:8080;
    server 192.168.101.2:8080;
}

If you have multiple servers listed at least_conn, and if multiple servers have a similarly low number of existing active connections, then among those servers, one will be selected on a weighted round-robin basis.

4. Installing Persistence or Sticky Nginx Load Balancing Algorithm

The downside to round-robin, and the least related method, is that a subsequent connection from the client will not go to the same server in the pool. This can be good for a session, no application specific.

But if your application depends on the session, then once the initial connection is made to a specific server, then you want all future connections from that specific client to go to the same server. To do this, use the ip_hash algorithm as shown below.

upstream crmdev {
    ip_hash;
    server 192.168.101.1:8080;
    server 192.168.101.2:8080;
}

Hash for IPv4 addresses, uses the first three octets. If it is an IPv6 address, the entire address is used.

5. Weighting factor parameters for individual servers

You can also specify the weight for a specific server in your pool. By default, all servers have the same priority (weight). those. the default weight is 1.

However, you can change this behavior by assigning a weight to the server as shown below.

upstream crmdev {
    server 192.168.101.1:8080;
    server 192.168.101.2:8080;
    server 192.168.101.3:8080 weight 2;
    server 192.168.101.4:8080;
    server 192.168.101.5:8080;
}

In this example, we have a total of 5 servers. But the weight to the 3rd server with a value of 2. This means that for every new request 6, 2 requests will go to the 3rd server, and the rest of the server will receive 1 request each.

Thus, it is useful to distribute more load on a particular server that has more capacity.

Although in the example above, the weight is used with the default circular algorithm, you can use the weight for least_conn and ip_hash as well.

6. Timeout parameters for individual servers – max_fails and fail_timeout

You can also specify max_fails and fail_timeout to a specific server, as shown below.

upstream crmdev {
    server 192.168.101.1:8080 max_fails=3 fail_timeout=30s;
    server 192.168.101.2:8080;
    server 192.168.101.3:8080 weight 2;
    server 192.168.101.4:8080;
    server 192.168.101.5:8080;
}

In the above:

  • The default fail_timeout is 10 seconds. In this example above, this is set to 30 seconds. This means that within 30 seconds, if there were x number of failed attempts (as defined by max_fails), then the server will be unavailable. In addition, the server will remain unavailable for 30 seconds.
  • by default max_fails is 1 try. In the example above, this is set to 3 tries. This means that after 3 unsuccessful attempts to connect to this particular server, Nginx will consider this server unavailable for the entire fail_timeout, which is 30 seconds.

7. Assign a backup server in Nginx LoadBalancer: Pool

In the following example, the 5th server is marked as backup using the “backup” keyword at the end of the server parameter.

upstream crmdev {
    server 192.168.101.1:8080 max_fails=3 fail_timeout=30s;
    server 192.168.101.2:8080;
    server 192.168.101.3:8080 weight 2;
    server 192.168.101.4:8080;
    server 192.168.101.5:8080 backup;
}

The example above will make a 5 server (192.168.101.5) as the backup server. An incoming request will not be forwarded to this server if all the other 4 servers are down.

Sidebar