How Do You Use the least_conn Directive in an Nginx Configuration File?

Problem scenario
You have configured Nginx to be an HTTP load balancer (a web server configured to behave as a landing portal that enables traffic to pass through).  As a reverse proxy with built-in keywords you have use the "least_conn" directive, but it does not seem to be working.  You want inbound network connection requests from your users via web browsers to be relayed to the web servers with the fewest (or least) amount of active connections.  Any Nginx server can work as a reverse proxy server like this.  In your instance you find that the special heuristic of conveying traffic to the available web server with the fewest current connections is not happening. 

You have placed the "least_conn;" directive in an "upstream backend {}" block in the /etc/nginx/conf.d/default.conf file of the distributor Nginx web server configured to be an HTTP load balancer.  However there is no evidence that the traffic is being routed to the underlying Nginx servers with the fewest connections.  Based on your testing, the traffic is evenly divided among the web servers with no regard for how many active connections persist.  This is consistent with the round-robin distribution method, Nginx's default routing mechanism.  It is as if the least_conn directive has been commented out.  What is wrong?

#1  Are the web pages small?  If they are purely text and less than 200 lines, that may be the reason.  When the web pages from at least one web server are very large, then the download process takes more time.  Individual connections of longer duration associated with bigger web pages (more than 1 MB) are more likely to be detected by the Nginx algorithm for traffic distribution purposes.  Active connections may have such a short duration that within your testing, the round robin method appears to be the prevailing distribution algorithm.  The round robin method is used if there are equal numbers of connections on each of the available web servers -- even when the least_conn directive has been used.  Unless there are unequal active connections on the web server the least_conn directive will have any influence.  Moreover, connections can be so short temporally with default "Welcome to Nginx" index.html pages, the least_conn will have no noticeable affect.  To test properly, copy some text to create the pages being downloaded to be disparate in size with at least one web server having a a web page that is 1 MB in size.

In a typical Nginx deployment, the index.html file is located here:  /usr/share/nginx/html/index.html

If you first installed Apache web sever before Nginx, the Nginx web service may present the /var/www/html/index.html file as the default web page.  You may want to modify it so the size  of at least one web page is VERY large.  This crucial to getting a test that will prove least_conn is working.

#2  Have you brought down Nginx services and brought them back up?  For the least_conn directive to take  effect for the first time, the Nginx service must be restarted.

#3  Are you testing properly?  Ideally you have two computers or servers that can both make web-based client requests that also perform comparably with reads/writes of web pages.  This way you can simulate a load of traffic simultaneously. Bandwidth, RAM, CPU, and hard disk I/O performance are all  factors.  A big difference could mean that that automated scripts are not running at exactly the same time.  Thus your simulated load is not creating active connections to test.  You should used cronjobs (with Unix/Linux servers) or Scheduled Tasks (with Windows  servers).  The activated task should be a script that repeatedly downloads the web page.  Once the job on each server has been invoked at a synchronized time for web-request contention, the script should save the the downloaded pages by appending them to the same file.  Ideally the content of the pages have something identifiable to the web server it came from (a unique string from its web server).  Once you have two aggregate files from two downloading processes that happened contemporaneously, you can use either Bash or PowerShell to count the identifying strings.  This way you can see evidence of which web server had the least connections and which had the most connections.

If the web page on one web server takes considerably longer, it will have more connections to it than the other web server.  But this is only apparent if there definitely are more active connections to one server than another.  Web servers must have different sizes of index.html files (or whatever file you are downloading from them) to be noticeable.

We tested Nginx in Docker containers as both the HTTP load balancer and as a web server.  The least_conn directive can work in this scenario (with Nginx in Docker as a reverse proxy relaying inbound connections to Nginx in Docker containers web servers).

If you want to need to troubleshoot problems with your Nginx load balancer, see this link.

Leave a comment

Your email address will not be published. Required fields are marked *